name: Update GeoLite2 Checksum

on:
  schedule:
    - cron: '0 2 * * 0'  # Weekly on Sundays at 2 AM UTC
  workflow_dispatch:

permissions:
  contents: write
  pull-requests: write
  issues: write

jobs:
  update-checksum:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Download and calculate checksum
        id: checksum
        run: |
          set -euo pipefail

          echo "📥 Downloading GeoLite2-Country.mmdb..."
          DOWNLOAD_URL="https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb"

          # Download with retry logic
          for i in {1..3}; do
            if curl -fsSL "$DOWNLOAD_URL" -o /tmp/geolite2.mmdb; then
              echo "✅ Download successful on attempt $i"
              break
            else
              echo "❌ Download failed on attempt $i"
              if [ "$i" -eq 3 ]; then
                echo "error=download_failed" >> "$GITHUB_OUTPUT"
                exit 1
              fi
              sleep 5
            fi
          done

          # Calculate checksum
          CURRENT=$(sha256sum /tmp/geolite2.mmdb | cut -d' ' -f1)

          # Validate checksum format (64 hex characters)
          if ! [[ "$CURRENT" =~ ^[a-f0-9]{64}$ ]]; then
            echo "❌ Invalid checksum format: $CURRENT"
            echo "error=invalid_checksum_format" >> "$GITHUB_OUTPUT"
            exit 1
          fi

          # Extract current checksum from Dockerfile
          OLD=$(grep "ARG GEOLITE2_COUNTRY_SHA256=" Dockerfile | cut -d'=' -f2)

          # Validate old checksum format
          if ! [[ "$OLD" =~ ^[a-f0-9]{64}$ ]]; then
            echo "❌ Invalid old checksum format in Dockerfile: $OLD"
            echo "error=invalid_dockerfile_checksum" >> "$GITHUB_OUTPUT"
            exit 1
          fi

          echo "🔍 Checksum comparison:"
          echo "   Current (Dockerfile): $OLD"
          echo "   Latest (Downloaded):  $CURRENT"

          echo "current=$CURRENT" >> "$GITHUB_OUTPUT"
          echo "old=$OLD" >> "$GITHUB_OUTPUT"

          if [ "$CURRENT" != "$OLD" ]; then
            echo "needs_update=true" >> "$GITHUB_OUTPUT"
            echo "⚠️  Checksum mismatch detected - update required"
          else
            echo "needs_update=false" >> "$GITHUB_OUTPUT"
            echo "✅ Checksum matches - no update needed"
          fi

      - name: Update Dockerfile
        if: steps.checksum.outputs.needs_update == 'true'
        run: |
          set -euo pipefail

          echo "📝 Updating Dockerfile with new checksum..."
          sed -i "s/ARG GEOLITE2_COUNTRY_SHA256=.*/ARG GEOLITE2_COUNTRY_SHA256=${{ steps.checksum.outputs.current }}/" Dockerfile

          # Verify the change was applied
          if ! grep -q "ARG GEOLITE2_COUNTRY_SHA256=${{ steps.checksum.outputs.current }}" Dockerfile; then
            echo "❌ Failed to update Dockerfile"
            exit 1
          fi

          echo "✅ Dockerfile updated successfully"

      - name: Verify Dockerfile syntax
        if: steps.checksum.outputs.needs_update == 'true'
        run: |
          set -euo pipefail

          echo "🔍 Verifying Dockerfile syntax..."
          # Use BuildKit's --check flag for syntax validation (no actual build)
          DOCKER_BUILDKIT=1 docker build --check -f Dockerfile . 2>&1 || {
            echo "❌ Dockerfile syntax validation failed"
            exit 1
          }
          echo "✅ Dockerfile syntax is valid"

      - name: Create Pull Request
        if: steps.checksum.outputs.needs_update == 'true'
        uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
        with:
          title: "chore(docker): update GeoLite2-Country.mmdb checksum"
          body: |
            🤖 **Automated GeoLite2 Database Checksum Update**

            The GeoLite2-Country.mmdb database has been updated upstream.

            ### Changes
            - **Old checksum:** `${{ steps.checksum.outputs.old }}`
            - **New checksum:** `${{ steps.checksum.outputs.current }}`
            - **File modified:** `Dockerfile` (line 352)

            ### Verification Required
            - [ ] Local build passes: `docker build --no-cache -t test .`
            - [ ] Container starts successfully
            - [ ] API health check responds: `curl http://localhost:8080/api/v1/health`
            - [ ] CI build passes

            ### Testing Commands
            ```bash
            # Verify checksum locally
            curl -fsSL "https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb" | sha256sum

            # Build and test
            docker build --no-cache --pull -t charon:test-geolite2 .
            docker run --rm charon:test-geolite2 /app/charon --version
            ```

            ### Related Documentation
            - [Dockerfile](/Dockerfile#L352)
            - [Implementation Plan](/docs/plans/current_spec.md)

            ---

            **Auto-generated by:** `.github/workflows/update-geolite2.yml`
            - **Trigger:** Scheduled weekly check (Sundays 2 AM UTC)
          base: development
          branch: bot/update-geolite2-checksum
          delete-branch: true
          commit-message: |
            chore(docker): update GeoLite2-Country.mmdb checksum

            Automated checksum update for GeoLite2-Country.mmdb database.

            Old: ${{ steps.checksum.outputs.old }}
            New: ${{ steps.checksum.outputs.current }}

            Auto-generated by: .github/workflows/update-geolite2.yml
          labels: |
            dependencies
            automated
            docker

      - name: Report failure via GitHub Issue
        if: failure()
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
        with:
          script: |
            const errorType = '${{ steps.checksum.outputs.error }}' || 'unknown';
            const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;

            const errorMessages = {
              'download_failed': '❌ Failed to download GeoLite2-Country.mmdb after 3 attempts',
              'invalid_checksum_format': '❌ Downloaded file produced invalid checksum format',
              'invalid_dockerfile_checksum': '❌ Current Dockerfile contains invalid checksum format',
              'unknown': '❌ Workflow failed with unknown error'
            };

            const title = `🚨 GeoLite2 Checksum Update Failed (${errorType})`;
            const body = `
            ## Automated GeoLite2 Update Workflow Failed

            **Error Type:** \`${errorType}\`
            **Error Message:** ${errorMessages[errorType] || errorMessages.unknown}

            ### Workflow Details
            - **Run URL:** ${runUrl}
            - **Triggered:** ${context.eventName === 'schedule' ? 'Scheduled (weekly, Sundays)' : 'Manual dispatch'}
            - **Timestamp:** ${new Date().toISOString()}

            ### Required Actions
            1. Review workflow logs: ${runUrl}
            2. Check upstream source availability: https://github.com/P3TERX/GeoLite.mmdb
            3. Verify network connectivity from GitHub Actions runners
            4. If upstream is unavailable, consider alternative sources

            ### Manual Update (if needed)
            \`\`\`bash
            # Download and verify checksum
            curl -fsSL "https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb" | sha256sum

            # Update Dockerfile line 352
            vim Dockerfile  # or use sed

            # Test build
            docker build --no-cache -t test .
            \`\`\`

            ### Related Documentation
            - [Implementation Plan](/docs/plans/current_spec.md)
            - [Workflow File](/.github/workflows/update-geolite2.yml)

            ---

            **Auto-generated by:** \`.github/workflows/update-geolite2.yml\`
            `;

            await github.rest.issues.create({
              owner: context.repo.owner,
              repo: context.repo.repo,
              title: title,
              body: body,
              labels: ['bug', 'automated', 'ci-cd', 'docker']
            });
