name: Release multi-platform executables

on:
  push:
    tags: ['v*.*.*']

permissions:
  contents: write
  id-token: write

jobs:
  build:
    name: build-${{ matrix.target }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            target: bun-linux-x64-baseline
          - os: ubuntu-latest
            target: bun-linux-arm64
          - os: macos-latest
            target: bun-darwin-x64
          - os: macos-latest
            target: bun-darwin-arm64
          - os: windows-latest
            target: bun-windows-x64-baseline
    runs-on: ${{ matrix.os }}
    env:
      BIN: backlog-bin${{ contains(matrix.target,'windows') && '.exe' || '' }}
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v1
        with:
          bun-version: 1.3.3
      - uses: actions/cache@v4
        id: cache
        with:
          path: ~/.bun/install/cache
          key: ${{ runner.os }}-${{ matrix.target }}-bun-${{ hashFiles('**/bun.lock') }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.target }}-bun-
      - run: bun install --frozen-lockfile
      - name: Sync version to tag
        shell: bash
        run: |
          TAG="${GITHUB_REF##refs/tags/v}"
          jq ".version = \"$TAG\"" package.json > tmp.json && mv tmp.json package.json
      - name: Prime Bun cache for baseline target (Windows workaround)
        if: ${{ contains(matrix.target, 'baseline') && contains(matrix.target, 'windows') }}
        shell: bash
        run: |
          # Workaround for https://github.com/oven-sh/bun/issues/13513
          # Build a dummy project from C:\ to prime the baseline binary cache
          cd /c
          mkdir -p bun-cache-primer
          cd bun-cache-primer
          echo 'console.log("cache primer")' > index.js
          bun build --compile --target=${{ matrix.target }} ./index.js --outfile primer.exe || true
          cd $GITHUB_WORKSPACE
      - name: Compile standalone binary
        shell: bash
        run: |
          mkdir -p dist
          bun build src/cli.ts --compile --minify --target=${{ matrix.target }} --define __EMBEDDED_VERSION__="\"${GITHUB_REF##refs/tags/v}\"" --outfile=dist/${{ env.BIN }}
      - name: Make binary executable (non-Windows)
        if: ${{ !contains(matrix.target,'windows') }}
        run: chmod +x "dist/${{ env.BIN }}"
      - name: Check build output and move binary
        shell: bash
        run: |
          echo "Contents of dist/:"
          ls -la dist/
          echo "Moving dist/${{ env.BIN }} to ${{ env.BIN }}"
          mv dist/${{ env.BIN }} ${{ env.BIN }}
          echo "Final binary size:"
          ls -lh ${{ env.BIN }}
      - uses: actions/upload-artifact@v4
        with:
          name: backlog-${{ matrix.target }}
          path: ${{ env.BIN }}

  npm-publish:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Prepare npm package
        shell: bash
        run: |
          mkdir -p dist
          cp scripts/cli.cjs dist/cli.js
          cp scripts/resolveBinary.cjs dist/resolveBinary.cjs
          cp scripts/postuninstall.cjs dist/postuninstall.cjs
          chmod +x dist/cli.js
      - name: Create npm-ready package.json
        shell: bash
        run: |
          TAG="${GITHUB_REF##refs/tags/v}"
          jq 'del(.devDependencies,.scripts.prepare,.scripts.preinstall,.type) |
              .version = "'$TAG'" |
              .bin = {backlog:"cli.js"} |
              .files = ["cli.js","resolveBinary.cjs","postuninstall.cjs","package.json","README.md","LICENSE"] |
              .scripts = {"postuninstall": "node postuninstall.cjs"} |
              .repository = {"type":"git","url":"https://github.com/MrLesk/Backlog.md"} |
              .optionalDependencies = {
                "backlog.md-linux-x64"  : "'$TAG'",
                "backlog.md-linux-arm64": "'$TAG'",
                "backlog.md-darwin-x64" : "'$TAG'",
                "backlog.md-darwin-arm64": "'$TAG'",
                "backlog.md-windows-x64": "'$TAG'"
              }' package.json > dist/package.json
          cp LICENSE README.md dist/ 2>/dev/null || true
      - uses: actions/setup-node@v5
        with:
          node-version: 20
      - name: Configure npm for trusted publishing
        shell: bash
        run: |
          set -euo pipefail
          npm install -g npm@11.6.0
          npm --version
      - name: Dry run trusted publish
        run: |
          cd dist
          npm publish --access public --dry-run
      - name: Publish to npm
        run: |
          cd dist
          npm publish --access public

  publish-binaries:
    needs: [build, npm-publish]
    strategy:
      matrix:
        include:
          - target: bun-linux-x64-baseline
            package: backlog.md-linux-x64
            os: linux
            cpu: x64
          - target: bun-linux-arm64
            package: backlog.md-linux-arm64
            os: linux
            cpu: arm64
          - target: bun-darwin-x64
            package: backlog.md-darwin-x64
            os: darwin
            cpu: x64
          - target: bun-darwin-arm64
            package: backlog.md-darwin-arm64
            os: darwin
            cpu: arm64
          - target: bun-windows-x64-baseline
            package: backlog.md-windows-x64
            os: win32
            cpu: x64
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: backlog-${{ matrix.target }}
        timeout-minutes: 15
      - name: Prepare package
        shell: bash
        run: |
          TAG="${GITHUB_REF##refs/tags/v}"
          mkdir -p pkg
          # Rename the binary to the expected name
          if [[ -f backlog-bin.exe ]]; then
            mv backlog-bin.exe pkg/backlog.exe
          elif [[ -f backlog-bin ]]; then
            mv backlog-bin pkg/backlog
          else
            echo "Error: No binary found"
            ls -la
            exit 1
          fi
          cp LICENSE README.md pkg/ 2>/dev/null || true
          cat <<EOF > pkg/package.json
          {
            "name": "${{ matrix.package }}",
            "version": "${TAG}",
            "os": ["${{ matrix.os }}"],
            "cpu": ["${{ matrix.cpu }}"],
            "files": ["backlog${{ contains(matrix.target,'windows') && '.exe' || '' }}","package.json","LICENSE"],
            "repository": {
              "type": "git",
              "url": "https://github.com/MrLesk/Backlog.md"
            }
          }
          EOF
      - name: Ensure executable permission (non-Windows)
        if: ${{ !contains(matrix.target,'windows') }}
        shell: bash
        run: |
          chmod +x pkg/backlog
      - uses: actions/setup-node@v5
        with:
          node-version: 20
      - name: Configure npm for trusted publishing
        shell: bash
        run: |
          set -euo pipefail
          npm install -g npm@11.6.0
          npm --version
      - name: Dry run platform publish
        run: |
          cd pkg
          npm publish --access public --dry-run
      - name: Publish platform package
        run: |
          cd pkg
          npm publish --access public

  install-sanity:
    name: install-sanity-${{ matrix.os }}
    needs: [publish-binaries, npm-publish]
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/setup-node@v5
        with:
          node-version: 20
          registry-url: https://registry.npmjs.org
      - name: Install and run backlog -v (Unix)
        if: ${{ matrix.os != 'windows-latest' }}
        shell: bash
        run: |
          set -euxo pipefail
          VERSION="${GITHUB_REF##refs/tags/v}"
          mkdir sanity && cd sanity
          npm init -y >/dev/null 2>&1
          npm i "backlog.md@${VERSION}"
          npx backlog -v
      - name: Install and run backlog -v (Windows)
        if: ${{ matrix.os == 'windows-latest' }}
        shell: pwsh
        run: |
          $ErrorActionPreference = 'Stop'
          $Version = $env:GITHUB_REF_NAME.TrimStart('v')
          mkdir sanity | Out-Null
          Set-Location sanity
          npm init -y | Out-Null
          npm i "backlog.md@$Version"
          npx backlog -v

  github-release:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          path: release-assets
        timeout-minutes: 15
      - name: Rename binaries for release
        run: |
          echo "=== Debug: Downloaded artifacts ==="
          find release-assets -type f -exec ls -lh {} \;
          echo "=== Processing artifacts ==="
          mkdir -p binaries
          for dir in release-assets/*/; do
            if [ -d "$dir" ]; then
              target=$(basename "$dir" | sed 's/backlog-//')
              echo "Processing target: $target"
              echo "Directory contents:"
              ls -la "$dir"
              binary=$(find "$dir" -name "backlog-bin*" -type f)
              if [ -n "$binary" ]; then
                echo "Found binary: $binary ($(ls -lh "$binary" | awk '{print $5}'))"
                if [[ "$target" == *"windows"* ]] && [[ "$binary" == *".exe" ]]; then
                  cp "$binary" "binaries/backlog-${target}.exe"
                  echo "Copied to binaries/backlog-${target}.exe ($(ls -lh "binaries/backlog-${target}.exe" | awk '{print $5}'))"
                else
                  cp "$binary" "binaries/backlog-${target}"
                  echo "Copied to binaries/backlog-${target} ($(ls -lh "binaries/backlog-${target}" | awk '{print $5}'))"
                fi
              fi
            fi
          done
          echo "=== Final binaries ==="
          ls -lh binaries/
      - uses: softprops/action-gh-release@v1
        with:
          files: binaries/*

  update-readme:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v1
        with:
          bun-version: 1.3.3
      - run: bun install --frozen-lockfile
      - name: Sync version to tag
        shell: bash
        run: |
          TAG="${GITHUB_REF##refs/tags/v}"
          jq ".version = \"$TAG\"" package.json > tmp.json && mv tmp.json package.json
      - name: Export board to README with version
        shell: bash
        run: |
          TAG="${GITHUB_REF##refs/tags/v}"
          bun run cli board export --readme --export-version "v$TAG"
      - name: Commit changes
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: "docs: update README with latest board status and version [skip ci]"
          branch: main
          file_pattern: README.md package.json
