name: Build and Release Electron App

on:
  push:
    tags:
      - "v*.*.*" # Triggers on version tags like v1.0.0
  workflow_dispatch: # Allows manual triggering
    inputs:
      version:
        description: "Version to release (e.g., v1.0.0)"
        required: true
        default: "v0.1.0"

jobs:
  build-and-release:
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: macos-latest
            name: macOS
            artifact-name: macos-builds
          - os: windows-latest
            name: Windows
            artifact-name: windows-builds
          - os: ubuntu-latest
            name: Linux
            artifact-name: linux-builds

    runs-on: ${{ matrix.os }}

    permissions:
      contents: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "npm"
          cache-dependency-path: package-lock.json

      - name: Configure Git for HTTPS
        # Convert SSH URLs to HTTPS for git dependencies (e.g., @electron/node-gyp)
        # This is needed because SSH authentication isn't available in CI
        run: git config --global url."https://github.com/".insteadOf "git@github.com:"

      - name: Install dependencies
        # Use npm install instead of npm ci to correctly resolve platform-specific
        # optional dependencies (e.g., @tailwindcss/oxide, lightningcss binaries)
        run: npm install

      - name: Install Linux native bindings
        # Workaround for npm optional dependencies bug (npm/cli#4828)
        # Only needed on Linux - macOS and Windows get their bindings automatically
        if: matrix.os == 'ubuntu-latest'
        run: |
          npm install --no-save --force \
            @rollup/rollup-linux-x64-gnu@4.53.3 \
            @tailwindcss/oxide-linux-x64-gnu@4.1.17

      - name: Extract and set version
        id: version
        shell: bash
        run: |
          VERSION_TAG="${{ github.event.inputs.version || github.ref_name }}"
          # Remove 'v' prefix if present (e.g., v1.0.0 -> 1.0.0)
          VERSION="${VERSION_TAG#v}"
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "Extracted version: $VERSION from tag: $VERSION_TAG"
          # Update the app's package.json version
          cd apps/app
          npm version $VERSION --no-git-tag-version
          cd ../..
          echo "Updated apps/app/package.json to version $VERSION"

      - name: Build Electron App (macOS)
        if: matrix.os == 'macos-latest'
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: npm run build:electron -- --mac --x64 --arm64

      - name: Build Electron App (Windows)
        if: matrix.os == 'windows-latest'
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: npm run build:electron -- --win --x64

      - name: Build Electron App (Linux)
        if: matrix.os == 'ubuntu-latest'
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: npm run build:electron -- --linux --x64

      - name: Upload Release Assets
        uses: softprops/action-gh-release@v1
        with:
          tag_name: ${{ github.event.inputs.version || github.ref_name }}
          files: |
            apps/app/dist/*.exe
            apps/app/dist/*.dmg
            apps/app/dist/*.AppImage
            apps/app/dist/*.zip
            apps/app/dist/*.deb
            apps/app/dist/*.rpm
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload macOS artifacts for R2
        if: matrix.os == 'macos-latest'
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.artifact-name }}
          path: apps/app/dist/*.dmg
          retention-days: 1

      - name: Upload Windows artifacts for R2
        if: matrix.os == 'windows-latest'
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.artifact-name }}
          path: apps/app/dist/*.exe
          retention-days: 1

      - name: Upload Linux artifacts for R2
        if: matrix.os == 'ubuntu-latest'
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.artifact-name }}
          path: apps/app/dist/*.AppImage
          retention-days: 1

  upload-to-r2:
    needs: build-and-release
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"

      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts

      - name: Install AWS SDK
        run: npm install @aws-sdk/client-s3

      - name: Extract version
        id: version
        shell: bash
        run: |
          VERSION_TAG="${{ github.event.inputs.version || github.ref_name }}"
          # Remove 'v' prefix if present (e.g., v1.0.0 -> 1.0.0)
          VERSION="${VERSION_TAG#v}"
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "version_tag=$VERSION_TAG" >> $GITHUB_OUTPUT
          echo "Extracted version: $VERSION from tag: $VERSION_TAG"

      - name: Upload to R2 and update releases.json
        env:
          R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
          R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
          R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
          R2_BUCKET_NAME: ${{ secrets.R2_BUCKET_NAME }}
          R2_PUBLIC_URL: ${{ secrets.R2_PUBLIC_URL }}
          RELEASE_VERSION: ${{ steps.version.outputs.version }}
          RELEASE_TAG: ${{ steps.version.outputs.version_tag }}
          GITHUB_REPOSITORY: ${{ github.repository }}
        run: node .github/scripts/upload-to-r2.js
