name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: "0 6 * * 1"

jobs:
  build-and-scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v7
        with:
          fetch-depth: 0
          persist-credentials: false

      - name: Build Docker image
        run: |
          docker build -t lumeex:ci . 2>&1 | tee build.log
          if grep -q "Building wheel for" build.log; then
            echo "::warning::A dependency was built from source — check Python/Alpine compatibility"
          fi

      - name: Smoke test (syntax check)
        run: |
          docker run --rm --entrypoint python lumeex:ci -c "
          import ast
          ok = True
          for f in ('build.py', 'gallery.py'):
              with open(f) as fh:
                  source = fh.read()
              try:
                  ast.parse(source)
              except SyntaxError as e:
                  print(f'::error::Syntax error in {f}: {e}')
                  ok = False
          if not ok:
              exit(1)
          print('OK: syntax is valid')
          "

      - name: Run unit tests
        run: |
          docker build --target test -t lumeex:test .
          docker run --rm lumeex:test pytest -v

      - name: Check deprecation warnings
        run: |
          docker run --rm --entrypoint python lumeex:ci -W error::DeprecationWarning -c "import src.py.webui.webui" 2>&1 | tee deprecation.log || true
          if grep -qi "deprecat" deprecation.log; then
            echo "::warning::Deprecation warning detected, check logs"
          fi

      - name: Scan with Trivy (critical - blocking)
        run: |
          docker run --rm \
            -e DOCKER_HOST=tcp://dockerhost:2375 \
            --add-host=dockerhost:host-gateway \
            aquasec/trivy:0.74.0 image --exit-code 1 --severity CRITICAL lumeex:ci

      - name: Scan with Trivy (high - informative)
        run: |
          docker run --rm \
            -e DOCKER_HOST=tcp://dockerhost:2375 \
            --add-host=dockerhost:host-gateway \
            aquasec/trivy:0.74.0 image --exit-code 0 --severity HIGH lumeex:ci

      - name: Publish tagged image
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        run: |
          BEFORE="${{ github.event.before }}"
          if [ -n "$BEFORE" ] && [ "$BEFORE" != "0000000000000000000000000000000000000000" ] && git cat-file -e "$BEFORE" 2>/dev/null; then
            BASE_REF="$BEFORE"
          else
            BASE_REF="HEAD~1"
          fi
          CHANGED=$(git diff --name-only "$BASE_REF" "${{ github.sha }}")
          echo "Changed files:"
          echo "$CHANGED"

          if ! echo "$CHANGED" | grep -qE '^(Dockerfile|requirements\.txt|VERSION|build\.py|gallery\.py)$|^(src|config)/|^docker/\.sh/entrypoint\.sh$'; then
            echo "No container-relevant file changed, skipping publish."
            exit 0
          fi

          if echo "$CHANGED" | grep -qE '^VERSION$'; then
            echo "VERSION was manually edited in this push, using it as-is."
          else
            echo "VERSION untouched but container files changed, auto-bumping the build number (Z)."
            OLD_VERSION=$(tr -d '[:space:]' < VERSION)
            IFS='.' read -r MAJOR MINOR PATCH <<< "$OLD_VERSION"
            NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
            echo "$NEW_VERSION" > VERSION

            git config user.name "lumeex-ci"
            git config user.email "ci@git.djeex.fr"
            git add VERSION
            git commit -m "Bump build version to $NEW_VERSION [skip ci]"

            # Belt and suspenders: actions/checkout can leave its own ephemeral
            # credential injected as an extraheader, which would silently override
            # the URL-embedded token below. persist-credentials:false on checkout
            # should already prevent this, but strip it here too just in case.
            git config --unset-all http.https://git.djeex.fr/.extraheader || true

            git push "https://Djeex:${{ secrets.CI_PUSH_TOKEN }}@git.djeex.fr/Djeex/lumeex.git" HEAD:main
          fi

          VERSION=$(tr -d '[:space:]' < VERSION)
          IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"
          MINOR_TAG="${MAJOR}.${MINOR}"

          IMAGE=git.djeex.fr/djeex/lumeex
          echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.djeex.fr -u Djeex --password-stdin

          # Retag the already-built, already-scanned image — never rebuild for publish,
          # so what ships is byte-for-byte what Trivy just scanned.
          docker tag lumeex:ci "$IMAGE:latest"
          docker tag lumeex:ci "$IMAGE:$MINOR_TAG"
          docker tag lumeex:ci "$IMAGE:$VERSION"
          docker push "$IMAGE:latest"
          docker push "$IMAGE:$MINOR_TAG"
          docker push "$IMAGE:$VERSION"

          TRIGGER_MSG=$(git log -1 --format=%s "${{ github.sha }}")
          PR_NUM=$(echo "$TRIGGER_MSG" | grep -oE '#[0-9]+' | head -1 | tr -d '#' || true)

          CATEGORY="🔧 Maintenance"
          CHANGE_TITLE="$TRIGGER_MSG"

          if [ -n "$PR_NUM" ]; then
            PR_JSON=$(curl -s -H "Authorization: token ${{ secrets.CI_PUSH_TOKEN }}" \
              "https://git.djeex.fr/api/v1/repos/Djeex/lumeex/pulls/$PR_NUM")
            PR_TITLE=$(echo "$PR_JSON" | jq -r '.title // empty' 2>/dev/null || true)
            LABELS=$(echo "$PR_JSON" | jq -r '.labels[]?.name' 2>/dev/null || true)

            if [ -n "$PR_TITLE" ]; then
              CHANGE_TITLE="$PR_TITLE"
            fi

            if echo "$LABELS" | grep -qx 'bug'; then
              CATEGORY="⚠️ Hotfix"
            elif echo "$LABELS" | grep -qx 'major'; then
              CATEGORY="💥 Breaking change"
            elif echo "$LABELS" | grep -qx 'minor'; then
              CATEGORY="✨ Update"
            fi
          fi

          REPO_URL="https://git.djeex.fr/Djeex/lumeex"
          COMMIT_LIST=$(git log --no-merges --format="- [%h](${REPO_URL}/commit/%H) %s" "$BASE_REF".."${{ github.sha }}")

          SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
          SOURCE_LINE="[${SHORT_SHA}](${REPO_URL}/commit/${{ github.sha }})"
          if [ -n "$PR_NUM" ]; then
            SOURCE_LINE="[#${PR_NUM}](${REPO_URL}/pulls/${PR_NUM}) · ${SOURCE_LINE}"
          fi

          BODY=$(cat <<EOF
          ## Changelog
          ---

          ### ${CATEGORY}
          ---
          ${CHANGE_TITLE}

          **Source:** ${SOURCE_LINE}
          **Image:** \`${IMAGE}:${VERSION}\`

          **Commits:**
          ${COMMIT_LIST}
          EOF
          )

          JSON_PAYLOAD=$(jq -n \
            --arg tag "$VERSION" \
            --arg name "$VERSION" \
            --arg body "$BODY" \
            '{tag_name: $tag, name: $name, target_commitish: "main", body: $body}')

          curl -s -o /dev/null -w "Release API response: %{http_code}\n" -X POST \
            -H "Authorization: token ${{ secrets.CI_PUSH_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d "$JSON_PAYLOAD" \
            "https://git.djeex.fr/api/v1/repos/Djeex/lumeex/releases"
