name: Notarize macOS

on:
  workflow_run:
    workflows: ["Release macOS"]
    types: [completed]
  workflow_dispatch:
    inputs:
      version:
        description: "Version (auto-detected from latest release if empty)"
        required: false
      run_id:
        description: "Release macOS workflow run ID (auto-detected if empty)"
        required: false

permissions:
  contents: write
  actions: write

concurrency:
  group: notarize-${{ github.event.workflow_run.head_branch || github.run_id }}
  cancel-in-progress: true

jobs:
  # ===================================================================
  # Resolve version + macOS build run_id automatically
  # ===================================================================
  resolve:
    runs-on: ubuntu-latest
    if: >
      github.event_name == 'workflow_dispatch' ||
      (github.event.workflow_run.conclusion == 'success' &&
       startsWith(github.event.workflow_run.head_branch, 'v'))
    outputs:
      version: ${{ steps.resolve.outputs.version }}
      run_id: ${{ steps.resolve.outputs.run_id }}
    steps:
      - name: Resolve version and run_id
        id: resolve
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            VERSION="${{ github.event.inputs.version }}"
            RUN_ID="${{ github.event.inputs.run_id }}"
            if [ -z "$VERSION" ]; then
              TAG=$(gh release view --repo "$GITHUB_REPOSITORY" --json tagName -q '.tagName')
              VERSION="${TAG#v}"
            fi
            if [ -z "$RUN_ID" ]; then
              RUN_ID=$(gh run list --repo "$GITHUB_REPOSITORY" \
                --workflow="Release macOS" --branch="v${VERSION}" --limit=1 \
                --json databaseId,conclusion --jq '.[] | select(.conclusion=="success") | .databaseId')
            fi
          else
            TAG="${{ github.event.workflow_run.head_branch }}"
            VERSION="${TAG#v}"
            RUN_ID="${{ github.event.workflow_run.id }}"
          fi

          if [ -z "$VERSION" ] || [ -z "$RUN_ID" ]; then
            echo "::error::Failed to resolve version='${VERSION}' run_id='${RUN_ID}'"
            exit 1
          fi

          echo "version=${VERSION}" >> $GITHUB_OUTPUT
          echo "run_id=${RUN_ID}" >> $GITHUB_OUTPUT
          echo "Resolved: version=${VERSION} run_id=${RUN_ID}"

  # ===================================================================
  # Notarize Yao binaries (arm64 + amd64)
  # ===================================================================
  notarize:
    needs: resolve
    runs-on: macos-latest
    strategy:
      matrix:
        arch: [arm64, amd64]
    steps:
      - name: Download Yao Binary
        uses: actions/download-artifact@v4
        with:
          name: yao-darwin-${{ matrix.arch }}
          path: bin
          run-id: ${{ needs.resolve.outputs.run_id }}
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Install Certificates
        env:
          KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
        run: |
          mkdir -p certs
          echo "${{ secrets.APPLE_DEVELOPERIDG2CA }}" | base64 --decode > certs/DeveloperIDG2CA.cer
          echo "${{ secrets.APPLE_DISTRIBUTION }}" | base64 --decode > certs/distribution.cer
          echo "${{ secrets.APPLE_PRIVATE_KEY }}" | base64 --decode > certs/private_key.p12
          security verify-cert -c certs/DeveloperIDG2CA.cer
          security verify-cert -c certs/distribution.cer

      - name: Import Certificates
        env:
          KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
        run: |
          KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
          security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
          security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security import ./certs/DeveloperIDG2CA.cer -k $KEYCHAIN_PATH -T /usr/bin/codesign
          security import ./certs/distribution.cer -k $KEYCHAIN_PATH -T /usr/bin/codesign
          security import ./certs/private_key.p12 -k $KEYCHAIN_PATH -P "${{ secrets.APPLE_PRIVATE_KEY_PASSWORD }}" -T /usr/bin/codesign
          security list-keychain -d user -s $KEYCHAIN_PATH

      - name: Verify Signature
        run: codesign --verify --deep --strict --verbose=2 bin/yao

      - name: Notarize Yao ${{ matrix.arch }}
        timeout-minutes: 15
        env:
          APPLE_ID: ${{ secrets.APPLE_ID }}
          APPLE_TEAME_ID: ${{ secrets.APPLE_TEAME_ID }}
          APPLE_APP_SPEC_PASS: ${{ secrets.APPLE_APP_SPEC_PASS }}
        run: |
          zip -j bin/yao.zip bin/yao

          SUBMIT_OUT=$(xcrun notarytool submit bin/yao.zip \
            --apple-id "$APPLE_ID" \
            --team-id "$APPLE_TEAME_ID" \
            --password "$APPLE_APP_SPEC_PASS" \
            --wait --timeout 10m --output-format json 2>&1) || true
          echo "$SUBMIT_OUT"

          STATUS=$(echo "$SUBMIT_OUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('status',''))" 2>/dev/null || true)
          SUB_ID=$(echo "$SUBMIT_OUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)

          if [ "$STATUS" != "Accepted" ]; then
            echo "::error::Yao ${{ matrix.arch }} notarization failed (status: $STATUS)"
            [ -n "$SUB_ID" ] && xcrun notarytool log "$SUB_ID" \
              --apple-id "$APPLE_ID" \
              --team-id "$APPLE_TEAME_ID" \
              --password "$APPLE_APP_SPEC_PASS" || true
            exit 1
          fi
          echo "Yao ${{ matrix.arch }} notarization accepted."

  # ===================================================================
  # After both architectures finish: wait for Linux R2, then trigger CDN
  # ===================================================================
  finalize:
    needs: [resolve, notarize]
    runs-on: ubuntu-latest
    if: success()
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
      R2_ENDPOINTS: ${{ secrets.R2_ENDPOINTS }}
      R2_BUCKET: ${{ secrets.R2_BUCKET || 'releases' }}
    steps:
      - name: Checkout (for gh CLI context)
        uses: actions/checkout@v4
        with:
          sparse-checkout: .github

      - name: Configure AWS CLI
        run: |
          aws configure set default.region us-east-1
          aws configure set default.s3.signature_version s3v4

      - name: Wait for all platform assets on R2
        run: |
          VERSION="${{ needs.resolve.outputs.version }}"
          PREFIX="yao/${VERSION}"

          PLATFORMS=(
            "darwin-arm64"
            "darwin-amd64"
            "linux-amd64"
            "linux-arm64"
          )

          for ATTEMPT in $(seq 1 30); do
            MISSING=0
            for P in "${PLATFORMS[@]}"; do
              KEY="${PREFIX}/yao-${VERSION}-${P}"
              if ! aws s3 ls "s3://${R2_BUCKET}/${KEY}" --endpoint-url "$R2_ENDPOINTS" >/dev/null 2>&1; then
                MISSING=$((MISSING+1))
              fi
              if ! aws s3 ls "s3://${R2_BUCKET}/${KEY}.sha256" --endpoint-url "$R2_ENDPOINTS" >/dev/null 2>&1; then
                MISSING=$((MISSING+1))
              fi
            done

            if [ "$MISSING" -eq 0 ]; then
              echo "All 4 platform assets verified on R2."
              exit 0
            fi

            echo "Attempt $ATTEMPT: $MISSING asset(s) still missing, waiting 30s..."
            sleep 30
          done

          echo "::error::Timed out waiting for all platform assets on R2."
          exit 1

      - name: Trigger CDN latest.json update
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          VERSION="${{ needs.resolve.outputs.version }}"
          gh workflow run update-cdn-latest.yml \
            -f version="${VERSION}" \
            -f mark_latest="true"
          echo "Triggered update-cdn-latest.yml for ${VERSION}"
