name: iOS TestFlight

on:
  workflow_dispatch:
    inputs:
      skip_upload:
        description: 'Skip TestFlight upload (build and archive only)'
        required: false
        default: 'false'
        type: boolean

permissions:
  contents: read
  actions: write

env:
  # Runner-specific build directory to allow parallel builds on multiple runners
  EAGLE0_BUILD_DIR: /tmp/eagle0-${{ github.run_id }}
  # Runner-specific keychain to avoid conflicts when multiple runners sign simultaneously
  KEYCHAIN_NAME: ios-build-${{ github.run_id }}.keychain

jobs:
  build-unity:
    runs-on: [self-hosted, macOS, unity-mac]
    outputs:
      xcode_project_path: ${{ steps.build.outputs.xcode_project_path }}

    steps:
      - name: Prune stale PR refs
        run: |
          # Self-hosted runners persist .git between runs. When a PR is updated,
          # old local refs (refs/remotes/pull/*/merge) may point to commits whose
          # objects were never fetched or have been pruned. Remove these stale refs
          # before checkout to prevent "missing object" errors.
          if [ -d ".git" ]; then
            echo "Pruning stale PR refs..."
            git for-each-ref --format='%(refname)' refs/remotes/pull/ 2>/dev/null | \
              xargs -r git update-ref -d 2>/dev/null || true
          fi
      - uses: actions/checkout@v4
        with:
          lfs: false  # Fetch LFS after checkout to avoid stale ref issues
          clean: true
          fetch-depth: 0

      - name: Fetch LFS files
        run: |
          git lfs install
          git lfs pull

      - name: Ensure Unity version installed
        run: ./ci/github_actions/ensure_unity_installed.sh ios

      - name: Restore Library/
        env:
          UNITY_CACHE_PLATFORM: ios
        run: ./ci/github_actions/restore_library.sh

      - name: Build iOS Unity Project
        id: build
        run: |
          ./ci/github_actions/build_unity_ios.sh "$EAGLE0_BUILD_DIR/eagle0iOS"
          echo "xcode_project_path=$EAGLE0_BUILD_DIR/eagle0iOS" >> $GITHUB_OUTPUT

      - name: Persist Library/
        if: success()
        env:
          UNITY_CACHE_PLATFORM: ios
        run: ./ci/github_actions/persist_library.sh

      - name: Upload Addressables to CDN
        if: success()
        env:
          ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
          SECRET_KEY: ${{ secrets.SECRET_KEY }}
        run: ./ci/github_actions/upload_addressables.sh iOS

      - name: Zip Xcode project for artifact
        run: |
          cd $EAGLE0_BUILD_DIR
          # Use tar for speed - Xcode projects have many small files
          tar -czf eagle0iOS.tar.gz eagle0iOS

      - name: Upload Xcode project
        uses: actions/upload-artifact@v4
        with:
          name: xcode-project-${{ github.run_id }}
          path: ${{ env.EAGLE0_BUILD_DIR }}/eagle0iOS.tar.gz
          retention-days: 1

      - name: Archive Build Log
        if: success() || failure()
        uses: actions/upload-artifact@v4
        with:
          name: editor_ios.log
          path: ${{ env.EAGLE0_BUILD_DIR }}/editor_ios.log
          retention-days: 5
      - name: Cleanup build directory
        if: always()
        run: rm -rf "${{ env.EAGLE0_BUILD_DIR }}"

  archive-and-upload:
    needs: build-unity
    runs-on: [self-hosted, macOS, unity-mac]

    steps:
      - uses: actions/checkout@v4
        with:
          sparse-checkout: |
            ci
            scripts

      - name: Clean download directory
        run: rm -rf $EAGLE0_BUILD_DIR/eagle0iOS

      - name: Download Xcode project
        uses: actions/download-artifact@v4
        with:
          name: xcode-project-${{ github.run_id }}
          path: ${{ env.EAGLE0_BUILD_DIR }}

      - name: Extract Xcode project
        run: |
          cd $EAGLE0_BUILD_DIR
          tar -xzf eagle0iOS.tar.gz
          rm eagle0iOS.tar.gz
          ls -la eagle0iOS/

      - name: Install Signing Certificate
        env:
          IOS_CERTIFICATE: ${{ secrets.IOS_CERTIFICATE }}
          IOS_CERTIFICATE_PWD: ${{ secrets.IOS_CERTIFICATE_PWD }}
        run: |
          # Generate random keychain password
          KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
          echo "KEYCHAIN_PASSWORD=$KEYCHAIN_PASSWORD" >> $GITHUB_ENV

          # Decode certificate
          echo "$IOS_CERTIFICATE" | base64 --decode > certificate.p12

          # Delete any existing keychain from previous runs
          security delete-keychain "$KEYCHAIN_NAME" 2>/dev/null || true

          # Create temporary keychain
          security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
          security default-keychain -s "$KEYCHAIN_NAME"
          security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
          security set-keychain-settings -t 3600 -u "$KEYCHAIN_NAME"

          # Import certificate
          security import certificate.p12 -k "$KEYCHAIN_NAME" -P "$IOS_CERTIFICATE_PWD" -T /usr/bin/codesign -T /usr/bin/security
          security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"

          # Add keychain to search list
          security list-keychains -d user -s "$KEYCHAIN_NAME" login.keychain

          rm certificate.p12

      - name: Install Provisioning Profile
        env:
          IOS_PROVISIONING_PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }}
        run: |
          # Decode provisioning profile
          echo "$IOS_PROVISIONING_PROFILE" | base64 --decode > profile.mobileprovision

          # Extract UUID from provisioning profile
          PROFILE_UUID=$(/usr/libexec/PlistBuddy -c "Print :UUID" /dev/stdin <<< $(security cms -D -i profile.mobileprovision))
          echo "PROFILE_UUID=$PROFILE_UUID" >> $GITHUB_ENV

          # Install to standard location
          mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
          cp profile.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/$PROFILE_UUID.mobileprovision

          rm profile.mobileprovision
          echo "Installed provisioning profile: $PROFILE_UUID"

      - name: Archive and Export IPA
        env:
          APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
        run: |
          chmod +x ./ci/github_actions/archive_ios.sh
          ./ci/github_actions/archive_ios.sh "$EAGLE0_BUILD_DIR/eagle0iOS" "$EAGLE0_BUILD_DIR/archive" "$APPLE_TEAM_ID" "$PROFILE_UUID"

      - name: Upload to TestFlight
        if: ${{ github.event.inputs.skip_upload != 'true' }}
        env:
          # App Store Connect API Key (replaces deprecated altool with Apple ID)
          # Create at: https://appstoreconnect.apple.com/access/api
          APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
          APP_STORE_CONNECT_API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }}
          APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
          APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
        run: |
          # Write API key to file (xcodebuild needs a file path)
          API_KEY_PATH=$(mktemp)
          echo "$APP_STORE_CONNECT_API_KEY" > "$API_KEY_PATH"
          export APP_STORE_CONNECT_API_KEY_PATH="$API_KEY_PATH"

          chmod +x ./ci/github_actions/upload_testflight.sh
          ./ci/github_actions/upload_testflight.sh "$EAGLE0_BUILD_DIR/archive/eagle0.xcarchive" "$APPLE_TEAM_ID" "$PROFILE_UUID"

          # Cleanup
          rm -f "$API_KEY_PATH"

      - name: Upload IPA artifact
        # Only keep artifact if we skipped TestFlight upload (for debugging)
        if: success() && github.event.inputs.skip_upload == 'true'
        uses: actions/upload-artifact@v4
        with:
          name: eagle0-ios-${{ github.run_id }}
          path: ${{ env.EAGLE0_BUILD_DIR }}/archive/eagle0.ipa
          retention-days: 1

      - name: Cleanup Keychain
        if: always()
        run: |
          security delete-keychain "$KEYCHAIN_NAME" 2>/dev/null || true
      - name: Cleanup build directory
        if: always()
        run: rm -rf "${{ env.EAGLE0_BUILD_DIR }}"

  cleanup:
    needs: [build-unity, archive-and-upload]
    if: always()
    runs-on: ubuntu-latest

    steps:
      - name: Delete intermediate artifacts
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          artifact_name="xcode-project-${{ github.run_id }}"
          echo "Deleting artifact: $artifact_name"
          artifact_id=$(gh api "repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts" \
            -q ".artifacts[] | select(.name == \"$artifact_name\") | .id")
          if [ -n "$artifact_id" ]; then
            gh api -X DELETE "repos/${{ github.repository }}/actions/artifacts/$artifact_id" || true
          fi
