name: Nightly Release Build

on:
  schedule:
    # Run at 2 AM UTC every day (10 PM EST / 7 PM PST)
    - cron: '0 2 * * *'
  workflow_dispatch:  # Allow manual triggering

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

jobs:
  release-build-test:
    name: Build and Test Release Configuration
    runs-on: [self-hosted, macOS, ARM64]
    timeout-minutes: 60
    
    steps:
    - name: Clean workspace
      run: |
        # Clean workspace for self-hosted runner
        # Clean workspace but preserve .git directory
        find . -maxdepth 1 -name '.*' -not -name '.git' -not -name '.' -not -name '..' -exec rm -rf {} + || true
        rm -rf * || true
        
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Verify Xcode
      run: |
        xcodebuild -version
        swift --version
    
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '24'
    
    - name: Setup pnpm
      uses: pnpm/action-setup@v4
      with:
        version: 9
        dest: ~/pnpm-${{ github.run_id }}
    
    - name: Cache Homebrew packages
      uses: actions/cache@v4
      continue-on-error: true
      with:
        path: |
          ~/Library/Caches/Homebrew
          /opt/homebrew/Cellar/swiftlint
          /opt/homebrew/Cellar/swiftformat
          /opt/homebrew/Cellar/xcbeautify
        key: ${{ runner.os }}-brew-${{ hashFiles('.github/workflows/mac.yml') }}
        restore-keys: |
          ${{ runner.os }}-brew-
    
    - name: Install tools
      run: |
        # Install or update required tools
        MAX_ATTEMPTS=3
        WAIT_TIME=5
        
        for attempt in $(seq 1 $MAX_ATTEMPTS); do
          echo "Tool installation attempt $attempt of $MAX_ATTEMPTS"
          
          # Check if another brew process is running
          if pgrep -x "brew" > /dev/null; then
            echo "Another brew process detected, waiting ${WAIT_TIME}s..."
            sleep $WAIT_TIME
            WAIT_TIME=$((WAIT_TIME * 2))  # Exponential backoff
            continue
          fi
          
          # Update Homebrew and install all tools in one command
          if brew update && brew install swiftlint swiftformat xcbeautify; then
            echo "Successfully installed/upgraded all tools"
            break
          else
            if [ $attempt -eq $MAX_ATTEMPTS ]; then
              echo "Failed to install tools after $MAX_ATTEMPTS attempts"
              exit 1
            fi
            echo "Command failed, waiting ${WAIT_TIME}s before retry..."
            sleep $WAIT_TIME
            WAIT_TIME=$((WAIT_TIME * 2))  # Exponential backoff
          fi
        done
        
        # Show versions
        echo "SwiftLint: $(swiftlint --version || echo 'not found')"
        echo "SwiftFormat: $(swiftformat --version || echo 'not found')"
        echo "xcbeautify: $(xcbeautify --version || echo 'not found')"
    
    - name: Cache pnpm store
      uses: actions/cache@v4
      continue-on-error: true
      with:
        path: ~/.local/share/pnpm/store
        key: ${{ runner.os }}-pnpm-store-${{ hashFiles('web/pnpm-lock.yaml') }}
        restore-keys: |
          ${{ runner.os }}-pnpm-store-

    - name: Install web dependencies
      run: |
        cd web
        # Clean any stale lock files
        rm -f .pnpm-store.lock .pnpm-debug.log || true
        # Set pnpm to use fewer workers to avoid crashes on self-hosted runners
        export NODE_OPTIONS="--max-old-space-size=4096"
        pnpm config set store-dir ~/.local/share/pnpm/store
        pnpm config set package-import-method hardlink
        # Install with retries
        for i in 1 2 3; do
          echo "Install attempt $i"
          if pnpm install --frozen-lockfile; then
            echo "pnpm install succeeded"
            # Force rebuild of native modules
            echo "Rebuilding native modules..."
            pnpm rebuild || true
            break
          else
            echo "pnpm install failed, cleaning and retrying..."
            rm -rf node_modules .pnpm-store.lock || true
            sleep 5
          fi
        done
    
    - name: Build web artifacts
      run: |
        echo "Building web artifacts..."
        cd web
        export CI=true
        pnpm run build
        echo "Web artifacts built successfully"
    
    - name: Resolve Dependencies
      run: |
        echo "Resolving Swift package dependencies..."
        xcodebuild -resolvePackageDependencies -workspace VibeTunnel.xcworkspace || echo "Dependency resolution completed"
    
    # BUILD RELEASE CONFIGURATION
    - name: Build Release (Universal Binary)
      timeout-minutes: 20
      run: |
        echo "Building Release configuration with universal binary..."
        set -o pipefail && \
        xcodebuild build \
          -workspace VibeTunnel.xcworkspace \
          -scheme VibeTunnel-Mac \
          -configuration Release \
          -destination "generic/platform=macOS" \
          -archivePath build/VibeTunnel.xcarchive \
          -showBuildTimingSummary \
          CODE_SIGN_IDENTITY="" \
          CODE_SIGNING_REQUIRED=NO \
          CODE_SIGNING_ALLOWED=NO \
          CODE_SIGN_ENTITLEMENTS="" \
          ENABLE_HARDENED_RUNTIME=NO \
          PROVISIONING_PROFILE_SPECIFIER="" \
          DEVELOPMENT_TEAM="" \
          ONLY_ACTIVE_ARCH=NO \
          ENABLE_TESTABILITY=YES \
          archive | xcbeautify
        
        echo "Release build completed successfully"
    
    # TEST RELEASE BUILD
    - name: Test Release Configuration
      timeout-minutes: 20
      run: |
        echo "Running tests on Release configuration..."
        set -o pipefail && \
        xcodebuild test \
          -workspace VibeTunnel.xcworkspace \
          -scheme VibeTunnel-Mac \
          -configuration Release \
          -destination "platform=macOS" \
          -enableCodeCoverage YES \
          -resultBundlePath TestResults-Release.xcresult \
          CODE_SIGN_IDENTITY="" \
          CODE_SIGNING_REQUIRED=NO \
          CODE_SIGNING_ALLOWED=NO \
          COMPILER_INDEX_STORE_ENABLE=NO \
          ENABLE_TESTABILITY=YES | xcbeautify || {
          echo "::error::Release configuration tests failed"
          # Try to get more detailed error information
          echo "=== Attempting to get test failure details ==="
          xcrun xcresulttool get --path TestResults-Release.xcresult --format json 2>/dev/null | jq '.issues._values[]? | select(.severity == "error")' 2>/dev/null || true
          exit 1
        }
        echo "Release tests completed successfully"
    
    # PERFORMANCE VALIDATION
    - name: Validate Release Binary
      run: |
        echo "=== Validating Release Binary ==="
        ARCHIVE_PATH="build/VibeTunnel.xcarchive"
        APP_PATH="$ARCHIVE_PATH/Products/Applications/VibeTunnel.app"
        
        if [ -d "$APP_PATH" ]; then
          echo "Found VibeTunnel.app at: $APP_PATH"
          
          # Check binary architectures
          echo -e "\n=== Binary Architecture ==="
          lipo -info "$APP_PATH/Contents/MacOS/VibeTunnel" || echo "Binary not found"
          
          # Check binary size
          echo -e "\n=== Binary Size ==="
          du -sh "$APP_PATH" || echo "Could not determine app size"
          
          # Check if optimizations were applied (Release should be smaller than Debug)
          echo -e "\n=== Optimization Check ==="
          # Look for debug symbols - Release builds should have minimal symbols
          nm "$APP_PATH/Contents/MacOS/VibeTunnel" 2>/dev/null | grep -c "debug" || echo "No debug symbols found (good for Release)"
          
          # Verify entitlements
          echo -e "\n=== Entitlements ==="
          codesign -d --entitlements - "$APP_PATH" 2>&1 || echo "No code signing (expected in CI)"
        else
          echo "::warning::Release archive not found at expected location"
        fi
    
    # NOTIFY ON FAILURE
    - name: Notify on Failure
      if: failure()
      uses: actions/github-script@v7
      with:
        script: |
          const issue = await github.rest.issues.create({
            owner: context.repo.owner,
            repo: context.repo.repo,
            title: `Nightly Release Build Failed - ${new Date().toISOString().split('T')[0]}`,
            body: `The nightly release build failed. Please check the [workflow run](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}) for details.`,
            labels: ['ci', 'nightly-build']
          });
          console.log(`Created issue #${issue.data.number}`);