name: Installer Build

on:
  push:
    branches: [ "main" ]
    paths:
      - ".github/workflows/installer_build.yml"
      - ".github/actions/setup-bazel/**"
      - "ci/github_actions/ensure_bazel_installed.sh"
      - ".bazelrc"
      - "src/main/go/net/eagle0/clients/win/installer/**"
  pull_request:
    paths:
      - ".github/workflows/installer_build.yml"
      - ".github/actions/setup-bazel/**"
      - "ci/github_actions/ensure_bazel_installed.sh"
      - ".bazelrc"
      - "src/main/go/net/eagle0/clients/win/installer/**"
  workflow_dispatch:

permissions:
  contents: read
  actions: write  # Required to delete artifacts after deploy

jobs:
  build-installer:
    runs-on: [self-hosted, bazel]

    steps:
      - name: Ensure Git LFS available for checkout
        run: |
          COMMON_PATHS=(/opt/homebrew/bin /usr/local/bin)
          for path in "${COMMON_PATHS[@]}"; do
            if [ -d "$path" ]; then
              echo "$path" >> "$GITHUB_PATH"
              export PATH="$path:$PATH"
            fi
          done

          if command -v git-lfs >/dev/null 2>&1; then
            git-lfs version
            exit 0
          fi

          brew install git-lfs
          git-lfs version
      - uses: actions/checkout@v7
        with:
          persist-credentials: false
          lfs: false
          clean: false

      - name: Setup Bazel
        uses: ./.github/actions/setup-bazel

      - name: Build Go installer for Windows
        env:
          MANIFEST_PUBLIC_KEY: ${{ secrets.MANIFEST_PUBLIC_KEY }}
        run: |
          # Require manifest public key for production builds
          if [ -z "$MANIFEST_PUBLIC_KEY" ]; then
            echo "ERROR: MANIFEST_PUBLIC_KEY secret is not set"
            echo "The installer requires a public key for manifest signature verification"
            exit 1
          fi

          # Build Windows installer with WebView GUI (uses CGO cross-compilation)
          # Use --action_env to pass the signing key into the genrule sandbox
          bazel build //src/main/go/net/eagle0/clients/win/installer:eagle_installer_windows_amd64_webview --stamp --action_env=MANIFEST_PUBLIC_KEY

          # Copy to output directory
          rm -rf ./installer-output
          mkdir -p ./installer-output
          cp bazel-bin/src/main/go/net/eagle0/clients/win/installer/Eagle0.exe ./installer-output/Eagle0.exe

          echo "Go installer size: $(ls -lh ./installer-output/Eagle0.exe | awk '{print $5}')"

      - name: Archive installer binary
        if: success() || failure()
        uses: actions/upload-artifact@v7
        with:
          name: eagle-installer
          path: ./installer-output/
          retention-days: 1

      - name: Verify installer exists
        if: success()
        run: |
          echo "=== Installer output directory ==="
          ls -lh ./installer-output/

          if [ ! -f "./installer-output/Eagle0.exe" ]; then
            echo "ERROR: Eagle0.exe not found"
            exit 1
          fi
          echo "Installer found"

      - name: Deploy installer
        if: success() && github.ref == 'refs/heads/main' && github.event_name == 'push'
        env:
          ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
          SECRET_KEY: ${{ secrets.SECRET_KEY }}
        run: |
          INSTALLER_PATH="$(pwd)/installer-output/Eagle0.exe"
          echo "Deploying Go installer to installer/Eagle0.exe"
          bazel run //src/main/go/net/eagle0/build/installer_build_handler:installer_build_handler -- "$INSTALLER_PATH" "installer/Eagle0.exe"

      - name: Update manifest
        if: success() && github.ref == 'refs/heads/main' && github.event_name == 'push'
        env:
          ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
          SECRET_KEY: ${{ secrets.SECRET_KEY }}
          MANIFEST_SIGNING_KEY: ${{ secrets.MANIFEST_SIGNING_KEY }}
        run: |
          INSTALLER_SHA=$(sha256sum ./installer-output/Eagle0.exe | cut -d' ' -f1)
          echo "installer_version=$INSTALLER_SHA" > /tmp/installer_manifest.txt
          echo "installer_url=installer/Eagle0.exe" >> /tmp/installer_manifest.txt

          echo "=== Manifest content ==="
          cat /tmp/installer_manifest.txt
          echo "========================"

          # Write signing key to temp file (if available)
          SIGNING_ARGS=""
          if [ -n "$MANIFEST_SIGNING_KEY" ]; then
            echo "$MANIFEST_SIGNING_KEY" > /tmp/manifest_signing_key
            chmod 600 /tmp/manifest_signing_key
            SIGNING_ARGS="/tmp/manifest_signing_key"
            echo "Manifest signing key available"
          else
            echo "Warning: MANIFEST_SIGNING_KEY not set, manifest will be unsigned"
          fi

          # Update the v2 manifest at installer/v2/eagle0_manifest.txt
          bazel run //src/main/go/net/eagle0/build/manifest_manager:manifest_manager -- installer-v2 /tmp/installer_manifest.txt $SIGNING_ARGS

          rm -f /tmp/manifest_signing_key

      - name: Delete all installer artifacts
        if: success() && github.ref == 'refs/heads/main' && github.event_name == 'push'
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: |
          # Delete ALL eagle-installer artifacts to free up storage
          echo "Fetching all eagle-installer artifacts..."
          page=1
          while true; do
            response=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
              "https://api.github.com/repos/${{ github.repository }}/actions/artifacts?per_page=100&page=$page")
            ids=$(echo "$response" | python3 -c "
          import json, sys
          data = json.load(sys.stdin)
          for a in data.get('artifacts', []):
              if a['name'] == 'eagle-installer':
                  print(a['id'])
          " 2>/dev/null)
            if [ -z "$ids" ]; then
              break
            fi
            for id in $ids; do
              echo "Deleting artifact ID: $id"
              curl -s -X DELETE -H "Authorization: Bearer $GITHUB_TOKEN" \
                "https://api.github.com/repos/${{ github.repository }}/actions/artifacts/$id" || true
            done
            page=$((page + 1))
          done
          echo "Cleanup complete"
