name: build

on:
  workflow_dispatch:
    inputs:
      logLevel:
        description: "Log level"
        required: true
        default: "warning"
        type: choice
        options:
          - info
          - warning
          - debug
      build:
        description: "Build"
        required: false
        default: false
        type: boolean
      update_readme:
        description: "Update Readme"
        required: false
        default: false
        type: boolean

  push:
    branches:
      - dev
      - master
    tags:
      - "v*"
    paths-ignore:
      - "**.md"
      - ".github/**"
  pull_request:
    branches:
      - "master"
    paths-ignore:
      - "**.md"
      - ".github/ISSUE_TEMPLATE/**"

env:
  DOCKERHUB_SLUG: arabcoders/ytptube
  GHCR_SLUG: ghcr.io/arabcoders/ytptube
  PNPM_VERSION: 10
  NODE_VERSION: 20

jobs:
  build-pr:
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: pnpm
          cache-dependency-path: "ui/pnpm-lock.yaml"

      - name: Install frontend dependencies & Build
        working-directory: ui
        run: |
          pnpm install --production --prefer-offline --frozen-lockfile
          pnpm run generate

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build commit to check.
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64
          push: false
          cache-from: type=gha, scope=${{ github.workflow }}
          cache-to: type=gha, mode=max, scope=${{ github.workflow }}

  push-build:
    runs-on: ubuntu-latest
    if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.build == 'true')
    permissions:
      packages: write
      contents: write
    env:
      PLATFORMS: ${{ startsWith(github.ref, 'refs/tags/v') && 'linux/amd64,linux/arm64' || 'linux/amd64' }}

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: pnpm
          cache-dependency-path: "ui/pnpm-lock.yaml"

      - name: Install frontend dependencies & Build
        working-directory: ui
        run: |
          pnpm install --production --prefer-offline --frozen-lockfile
          pnpm run generate

      - name: Install GitPython
        run: pip install gitpython

      - name: Generate CHANGELOG.json
        run: |
          python3 .github/scripts/generate_changelog.py -p . -f ./ui/exported/CHANGELOG.json

      - name: Update app/library/version.py
        run: |
          VERSION="${GITHUB_REF##*/}"
          SHA=$(git rev-parse HEAD)
          DATE=$(date -u +"%Y%m%d")
          BRANCH=$(echo "${GITHUB_REF#refs/heads/}" | sed 's/\//-/g')

          echo "Current version: ${VERSION}, Branch: ${BRANCH}, SHA: ${SHA}, Date: ${DATE}"

          echo "APP_VERSION=${VERSION}" >> $"$GITHUB_ENV"
          echo "APP_SHA=${SHA}" >> "$GITHUB_ENV"
          echo "APP_DATE=${DATE}" >> "$GITHUB_ENV"
          echo "APP_BRANCH=${BRANCH}" >> "$GITHUB_ENV"

          sed -i \
            -e "s/^APP_VERSION = \".*\"/APP_VERSION = \"${VERSION}\"/" \
            -e "s/^APP_COMMIT_SHA = \".*\"/APP_COMMIT_SHA = \"${SHA}\"/" \
            -e "s/^APP_BUILD_DATE = \".*\"/APP_BUILD_DATE = \"${DATE}\"/" \
            -e "s/^APP_BRANCH = \".*\"/APP_BRANCH = \"${BRANCH}\"/" \
            app/library/version.py

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: |
            ${{ env.DOCKERHUB_SLUG }}
            ${{ env.GHCR_SLUG }}
          tags: |
            type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
            type=ref,event=branch
            type=ref,event=tag
          flavor: |
            latest=false

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: ${{ env.PLATFORMS }}
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha, scope=${{ github.workflow }}
          cache-to: type=gha, mode=max, scope=${{ github.workflow }}

      - name: Overwrite GitHub release notes
        if: startsWith(github.ref, 'refs/tags/v')
        uses: actions/github-script@v6
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const tag = context.ref.replace('refs/tags/', '');

            const latestRelease = await github.rest.repos.listReleases({
              owner: context.repo.owner,
              repo: context.repo.repo,
            });

            const release = latestRelease.data.find(r => r.tag_name === tag);
            if (!release) {
              core.setFailed(`Release with tag ${tag} not found`);
              return;
            }

            const { data: comparison } = await github.rest.repos.compareCommits({
              owner: context.repo.owner,
              repo: context.repo.repo,
              base: latestRelease.data[1]?.tag_name || '', // fallback to second latest tag
              head: tag,
            });

            const commits = comparison.commits.filter(c => 1 === c.parents.length);

            const changelog = commits.map(
              c => `- ${c.sha.substring(0, 7)} ${c.commit.message.split('\n')[0]} by @${c.commit.author.name}`
            ).join('\n');

            if (!changelog) {
              core.setFailed('No commits found for the changelog');
              return;
            }

            console.log(`Changelog for ${tag}:\n${changelog}`);

            await github.rest.repos.updateRelease({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: release.id,
              body: changelog
            });

  dockerhub-sync-readme:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) || (github.event_name == 'workflow_dispatch' && github.event.inputs.update_readme == 'true')
    steps:
      - name: Sync README
        uses: docker://lsiodev/readme-sync:latest
        env:
          DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
          DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
          GIT_REPOSITORY: ${{ github.repository }}
          DOCKER_REPOSITORY: ${{ env.DOCKERHUB_SLUG }}
          GIT_BRANCH: master
        with:
          entrypoint: node
          args: /opt/docker-readme-sync/sync
