name: build

on:
  push:
    branches:
      - 'master'
    paths-ignore:
      - '**.md'

jobs:
  quality-checks:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v7
      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: lts/*
      - name: Enable pnpm
        run: corepack enable
      - name: Install frontend dependencies
        working-directory: ui
        run: pnpm install --frozen-lockfile
      - name: Run frontend lint
        working-directory: ui
        run: pnpm run lint
      - name: Build frontend
        working-directory: ui
        run: pnpm run build
      - name: Run frontend tests
        working-directory: ui
        run: pnpm exec ng test --watch=false
        env:
          CI: true
      - name: Install uv
        uses: astral-sh/setup-uv@v7
      - name: Install Python dependencies
        run: uv sync --frozen --group dev
      - name: Run backend smoke checks
        run: python -m compileall app
      - name: Run backend tests
        run: uv run pytest app/tests/
      - name: Run Trivy filesystem scan
        uses: aquasecurity/trivy-action@v0.36.0
        with:
          scan-type: fs
          scan-ref: .
          format: table
          severity: CRITICAL,HIGH

  dockerhub-build-push:
    needs: quality-checks
    runs-on: ubuntu-latest
    steps:
      -
        name: Get current date
        id: date
        run: echo "date=$(date +'%Y.%m.%d')" >> "$GITHUB_OUTPUT"
      -
        name: Checkout
        uses: actions/checkout@v7
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v4
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v4
      -
        name: Login to DockerHub
        uses: docker/login-action@v4
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Login to GitHub Container Registry
        uses: docker/login-action@v4
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      -
        name: Build and push
        uses: docker/build-push-action@v7
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          build-args: |
            VERSION=${{ steps.date.outputs.date }}
          tags: |
            ${{ secrets.DOCKERHUB_REPOSITORY }}:latest
            ${{ secrets.DOCKERHUB_REPOSITORY }}:${{ steps.date.outputs.date }}
            ghcr.io/${{ github.repository }}:latest
            ghcr.io/${{ github.repository }}:${{ steps.date.outputs.date }}

  dockerhub-sync-readme:
    needs: dockerhub-build-push
    runs-on: ubuntu-latest
    steps:
      - name: Sync README
        uses: docker://lsiodev/readme-sync:latest
        env:
          DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
          DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
          GIT_REPOSITORY: ${{ github.repository }}
          DOCKER_REPOSITORY: ${{ secrets.DOCKERHUB_REPOSITORY }}
          GIT_BRANCH: master
        with:
          entrypoint: node
          args: /opt/docker-readme-sync/sync

  create-release:
    needs: dockerhub-build-push
    runs-on: ubuntu-latest
    steps:
      - name: Get current date
        id: date
        run: echo "date=$(date +'%Y.%m.%d')" >> $GITHUB_OUTPUT
      - name: Checkout
        uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - name: Get commits since last release
        id: commits
        run: |
          # Fetch all tags
          git fetch --tags
          
          # Get the last tag (sorted by version, using date format YYYY.MM.DD)
          LAST_TAG=$(git tag -l --sort=-version:refname | grep -E '^[0-9]{4}\.[0-9]{2}\.[0-9]{2}$' | head -n 1)
          
          if [ -z "$LAST_TAG" ]; then
            # No previous release, skip commits for first release
            COMMITS=""
            echo "has_commits=false" >> $GITHUB_OUTPUT
          else
            # Get commits since last tag
            COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges)
            if [ -z "$COMMITS" ]; then
              echo "has_commits=false" >> $GITHUB_OUTPUT
            else
              echo "has_commits=true" >> $GITHUB_OUTPUT
            fi
          fi
          
          # Escape for use in YAML/multiline output
          {
            echo 'commits<<EOF'
            echo "$COMMITS"
            echo EOF
          } >> $GITHUB_OUTPUT
          
          # Also output for debugging
          echo "Last tag: ${LAST_TAG:-none}"
          echo "Commits since last release:"
          echo "$COMMITS"
      - name: Generate release body
        id: release_body
        env:
          DOCKERHUB_REPO: ${{ secrets.DOCKERHUB_REPOSITORY }}
          GHCR_REPO: ghcr.io/${{ github.repository }}
          DATE: ${{ steps.date.outputs.date }}
          HAS_COMMITS: ${{ steps.commits.outputs.has_commits }}
          COMMITS: ${{ steps.commits.outputs.commits }}
        run: |
          {
            echo '## Docker Images'
            echo ''
            echo 'Docker images have been built and pushed:'
            echo ''
            echo '**Docker Hub:**'
            echo "- \`${DOCKERHUB_REPO}:latest\`"
            echo "- \`${DOCKERHUB_REPO}:${DATE}\`"
            echo ''
            echo '**GitHub Container Registry:**'
            echo "- \`${GHCR_REPO}:latest\`"
            echo "- \`${GHCR_REPO}:${DATE}\`"
            
            if [ "$HAS_COMMITS" = "true" ] && [ -n "$COMMITS" ]; then
              echo ''
              echo '## Changes'
              echo ''
              echo "$COMMITS"
            fi
          } > release_body.txt
          
          {
            echo 'body<<EOF'
            cat release_body.txt
            echo EOF
          } >> $GITHUB_OUTPUT
      - name: Delete existing release if present
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TAG_NAME: ${{ steps.date.outputs.date }}
        run: |
          # Check if release exists and delete it
          if gh release view "$TAG_NAME" &>/dev/null; then
            echo "Release $TAG_NAME already exists, deleting it..."
            gh release delete "$TAG_NAME" --yes || true
          fi
          
          # Fetch tags to check remote
          git fetch --tags
          
          # Check if tag exists (locally or remotely) and delete it
          if git rev-parse "$TAG_NAME" &>/dev/null 2>&1 || git ls-remote --tags origin "$TAG_NAME" | grep -q "$TAG_NAME"; then
            echo "Tag $TAG_NAME already exists, deleting it..."
            git tag -d "$TAG_NAME" 2>/dev/null || true
            git push origin ":refs/tags/$TAG_NAME" || true
          fi
      - name: Create GitHub Release
        uses: softprops/action-gh-release@v3
        with:
          tag_name: ${{ steps.date.outputs.date }}
          name: Release ${{ steps.date.outputs.date }}
          body_path: release_body.txt
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
