name: Release macOS

on:
  push:
    tags:
      - "v*"

permissions:
  contents: write

jobs:
  # ===================================================================
  # Build Yao macOS binaries (arm64 + amd64) — one job, both arches
  # ===================================================================
  build:
    runs-on: macos-latest
    steps:
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 18

      - name: Install pnpm
        run: npm install -g pnpm

      - name: Setup Cache
        uses: actions/cache@v4
        with:
          path: |
            ~/.cache/go-build
            ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-

      - name: Checkout Kun
        uses: actions/checkout@v4
        with:
          repository: yaoapp/kun
          path: kun

      - name: Checkout Xun
        uses: actions/checkout@v4
        with:
          repository: yaoapp/xun
          path: xun

      - name: Checkout Gou
        uses: actions/checkout@v4
        with:
          repository: yaoapp/gou
          path: gou

      - name: Checkout V8Go
        uses: actions/checkout@v4
        with:
          repository: yaoapp/v8go
          path: v8go

      - name: Unzip libv8
        run: |
          files=$(find ./v8go -name "libv8*.zip")
          for file in $files; do
            dir=$(dirname "$file")
            echo "Extracting $file to directory $dir"
            unzip -o -d $dir $file
            rm -rf $dir/__MACOSX
          done

      - name: Checkout CUI v1.0
        uses: actions/checkout@v4
        with:
          repository: yaoapp/cui
          path: cui-v1.0

      - name: Checkout Yao-Init
        uses: actions/checkout@v4
        with:
          repository: yaoapp/yao-init
          path: yao-init

      - name: Move Dependencies
        run: |
          mv kun ../
          mv xun ../
          mv gou ../
          mv v8go ../
          mv cui-v1.0 ../
          mv yao-init ../
          rm -f ../cui-v1.0/packages/setup/vite.config.ts.*

      - name: Checkout Yao
        uses: actions/checkout@v4

      - name: Set Version from Tag
        run: |
          if [[ "$GITHUB_REF" != refs/tags/v* ]]; then
            echo "::error::This workflow requires a tag (refs/tags/v*). Got: $GITHUB_REF"
            exit 1
          fi
          TAG="${GITHUB_REF#refs/tags/v}"
          echo "Setting VERSION to $TAG"
          sed -i.bak "s/const VERSION = \".*\"/const VERSION = \"${TAG}\"/g" share/const.go
          rm -f share/const.go.bak
          grep 'const VERSION' share/const.go

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: "1.25"

      - name: Setup Go Tools
        run: make tools

      - name: Make Artifacts macOS
        run: make artifacts-macos

      - name: Get Version
        id: version
        run: |
          VERSION=$(grep 'const VERSION =' share/const.go | awk '{print $4}' | sed 's/"//g')
          echo "version=${VERSION}" >> $GITHUB_OUTPUT

      - name: List Build Output
        run: ls -lh dist/release/

      - 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: Sign Yao Binaries
        run: |
          VERSION="${{ steps.version.outputs.version }}"
          IDENTITY="Developer ID Application: ${{ secrets.APPLE_SIGN }}"
          for ARCH in arm64 amd64; do
            for SUFFIX in "" "-prod"; do
              BIN="dist/release/yao-${VERSION}-darwin-${ARCH}${SUFFIX}"
              codesign --force --verbose --timestamp --options runtime \
                --entitlements .github/codesign/entitlements.plist \
                --sign "$IDENTITY" "$BIN"
              codesign --verify --deep --strict --verbose=2 "$BIN"
            done
          done

      - name: Prepare Output and Checksums
        run: |
          VERSION="${{ steps.version.outputs.version }}"
          for ARCH in arm64 amd64; do
            for VARIANT in dev prod; do
              if [ "$VARIANT" = "dev" ]; then
                SRC="dist/release/yao-${VERSION}-darwin-${ARCH}"
              else
                SRC="dist/release/yao-${VERSION}-darwin-${ARCH}-prod"
              fi
              DIR="/tmp/yao-output-${ARCH}-${VARIANT}"
              mkdir -p "$DIR"
              cp "$SRC" "$DIR/yao"
              chmod +x "$DIR/yao"
            done
          done

          mkdir -p /tmp/checksums
          for ARCH in arm64 amd64; do
            for VARIANT in dev prod; do
              shasum -a 256 "/tmp/yao-output-${ARCH}-${VARIANT}/yao" | awk '{print $1"  yao"}' > "/tmp/checksums/yao-darwin-${ARCH}-${VARIANT}.sha256"
            done
          done
          cat /tmp/checksums/*.sha256

      - name: Upload Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: yao-darwin-arm64
          path: /tmp/yao-output-arm64-prod/yao

      - name: Upload arm64 Dev Binary
        uses: actions/upload-artifact@v4
        with:
          name: yao-darwin-arm64-dev
          path: /tmp/yao-output-arm64-dev/yao

      - name: Upload amd64 Binary
        uses: actions/upload-artifact@v4
        with:
          name: yao-darwin-amd64
          path: /tmp/yao-output-amd64-prod/yao

      - name: Upload amd64 Dev Binary
        uses: actions/upload-artifact@v4
        with:
          name: yao-darwin-amd64-dev
          path: /tmp/yao-output-amd64-dev/yao

      - name: Upload Checksums
        uses: actions/upload-artifact@v4
        with:
          name: yao-darwin-checksums
          path: /tmp/checksums/*.sha256

  # ===================================================================
  # GitHub Release + R2 Upload (macOS binaries)
  # ===================================================================
  release:
    needs: build
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    steps:
      - name: Get Version
        id: version
        run: |
          if [[ "$GITHUB_REF" != refs/tags/v* ]]; then
            echo "::error::This workflow requires a tag. Got: $GITHUB_REF"
            exit 1
          fi
          VERSION="${GITHUB_REF#refs/tags/v}"
          TAG="${GITHUB_REF#refs/tags/}"
          echo "version=${VERSION}" >> $GITHUB_OUTPUT
          echo "tag=${TAG}" >> $GITHUB_OUTPUT

      - name: Download macOS Artifacts
        uses: actions/download-artifact@v4
        with:
          name: yao-darwin-arm64
          path: artifacts/arm64-prod

      - name: Download arm64 Dev
        uses: actions/download-artifact@v4
        with:
          name: yao-darwin-arm64-dev
          path: artifacts/arm64-dev

      - name: Download amd64 Prod
        uses: actions/download-artifact@v4
        with:
          name: yao-darwin-amd64
          path: artifacts/amd64-prod

      - name: Download amd64 Dev
        uses: actions/download-artifact@v4
        with:
          name: yao-darwin-amd64-dev
          path: artifacts/amd64-dev

      - name: Download Checksums
        uses: actions/download-artifact@v4
        with:
          name: yao-darwin-checksums
          path: artifacts/checksums

      - name: Prepare Release Files
        run: |
          VERSION="${{ steps.version.outputs.version }}"
          mkdir -p release
          cp artifacts/arm64-prod/yao "release/yao-${VERSION}-darwin-arm64"
          cp artifacts/amd64-prod/yao "release/yao-${VERSION}-darwin-amd64"
          cp artifacts/arm64-dev/yao "release/yao-${VERSION}-darwin-arm64-dev"
          cp artifacts/amd64-dev/yao "release/yao-${VERSION}-darwin-amd64-dev"
          cp artifacts/checksums/*.sha256 release/ 2>/dev/null || true
          chmod +x release/yao-*
          ls -lh release/

      - name: Wait for Draft Release
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          TAG="${{ steps.version.outputs.tag }}"
          for i in $(seq 1 30); do
            if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" &>/dev/null; then
              echo "Draft release found for $TAG."
              exit 0
            fi
            echo "Waiting for draft release... ($i/30)"
            sleep 10
          done
          echo "::error::Timed out waiting for draft release $TAG"
          exit 1

      - name: Upload Assets to GitHub Release
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          TAG="${{ steps.version.outputs.tag }}"
          gh release upload "$TAG" release/* --repo "$GITHUB_REPOSITORY" --clobber

      - name: Publish Release if Complete
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          TAG="${{ steps.version.outputs.tag }}"
          ASSET_COUNT=$(gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets | length')
          echo "Current assets: $ASSET_COUNT / 16"
          if [ "$ASSET_COUNT" -ge 16 ]; then
            echo "All assets present, publishing release..."
            gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --draft=false --latest
          else
            echo "Assets incomplete ($ASSET_COUNT/16), waiting for other workflow to publish."
          fi

      - name: Upload macOS binaries to R2
        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' }}
        run: |
          aws configure set default.region us-east-1
          aws configure set default.s3.signature_version s3v4

          VERSION="${{ steps.version.outputs.version }}"
          PREFIX="yao/${VERSION}"

          for PLATFORM in darwin-arm64 darwin-amd64; do
            FILE="release/yao-${VERSION}-${PLATFORM}"
            NAME="yao-${VERSION}-${PLATFORM}"
            sha256sum "$FILE" | awk '{print $1}' > "/tmp/${NAME}.sha256"

            aws s3 cp "$FILE" "s3://${R2_BUCKET}/${PREFIX}/${NAME}" \
              --endpoint-url "$R2_ENDPOINTS" \
              --content-type "application/octet-stream"
            aws s3 cp "/tmp/${NAME}.sha256" "s3://${R2_BUCKET}/${PREFIX}/${NAME}.sha256" \
              --endpoint-url "$R2_ENDPOINTS" \
              --content-type "text/plain"
            echo "Uploaded: ${NAME} + ${NAME}.sha256"
          done
