name: Release

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

permissions:
  contents: write

jobs:
  build:
    strategy:
      matrix:
        include:
          - target: aarch64-apple-darwin
            os: macos-latest
            npm-dir: darwin-arm64
          - target: x86_64-apple-darwin
            os: macos-latest
            npm-dir: darwin-x64
          - target: x86_64-unknown-linux-musl
            os: ubuntu-latest
            npm-dir: linux-x64
          - target: aarch64-unknown-linux-musl
            os: ubuntu-latest
            npm-dir: linux-arm64
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}
      - uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.target }}

      - name: Install musl tools (Linux x64)
        if: matrix.target == 'x86_64-unknown-linux-musl'
        run: sudo apt-get update && sudo apt-get install -y musl-tools

      - name: Install cross-compilation tools (Linux ARM)
        if: matrix.target == 'aarch64-unknown-linux-musl'
        run: |
          sudo apt-get update
          sudo apt-get install -y gcc-aarch64-linux-gnu musl-tools
          mkdir -p .cargo
          echo '[target.aarch64-unknown-linux-musl]' >> .cargo/config.toml
          echo 'linker = "aarch64-linux-gnu-gcc"' >> .cargo/config.toml

      - name: Build
        run: cargo build --release --target ${{ matrix.target }}

      - name: Package for GitHub Release
        run: |
          cd target/${{ matrix.target }}/release
          tar czf ../../../cc-statusline-${{ matrix.target }}.tar.gz cc-statusline

      - name: Prepare npm platform package
        run: |
          VERSION="${GITHUB_REF_NAME#v}"
          mkdir -p npm/${{ matrix.npm-dir }}/bin
          cp target/${{ matrix.target }}/release/cc-statusline npm/${{ matrix.npm-dir }}/bin/
          chmod 755 npm/${{ matrix.npm-dir }}/bin/cc-statusline
          # Update version in platform package.json
          node -e "
            const pkg = require('./npm/${{ matrix.npm-dir }}/package.json');
            pkg.version = '${VERSION}';
            require('fs').writeFileSync(
              './npm/${{ matrix.npm-dir }}/package.json',
              JSON.stringify(pkg, null, 2) + '\n'
            );
          "

      - uses: actions/upload-artifact@v4
        with:
          name: binary-${{ matrix.target }}
          path: cc-statusline-${{ matrix.target }}.tar.gz

      - uses: actions/upload-artifact@v4
        with:
          name: npm-${{ matrix.npm-dir }}
          path: npm/${{ matrix.npm-dir }}/

  release:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          pattern: binary-*
          merge-multiple: true

      - name: Create GitHub Release
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          cat > /tmp/release-notes.md << 'EOF'
          ## Install

          - **npm**: `npx cc-statusline-tui@latest`
          - **cargo**: `cargo install cc-statusline-tui`
          - **brew**: `brew tap LokiQ0713/cc-statusline-tui && brew install cc-statusline`
          EOF
          gh release delete "$GITHUB_REF_NAME" --yes 2>/dev/null || true
          gh release create "$GITHUB_REF_NAME" \
            --title "$GITHUB_REF_NAME" \
            --notes-file /tmp/release-notes.md \
            --latest \
            *.tar.gz

  publish-npm:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org

      # Download all platform package artifacts
      - uses: actions/download-artifact@v4
        with:
          name: npm-darwin-arm64
          path: npm/darwin-arm64/
      - uses: actions/download-artifact@v4
        with:
          name: npm-darwin-x64
          path: npm/darwin-x64/
      - uses: actions/download-artifact@v4
        with:
          name: npm-linux-x64
          path: npm/linux-x64/
      - uses: actions/download-artifact@v4
        with:
          name: npm-linux-arm64
          path: npm/linux-arm64/

      # Ensure binaries are executable (artifacts may strip permissions)
      - name: Fix binary permissions
        run: chmod +x npm/*/bin/cc-statusline

      # Publish platform packages first, then main package
      - name: Publish platform packages
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: |
          for dir in npm/darwin-arm64 npm/darwin-x64 npm/linux-x64 npm/linux-arm64; do
            echo "Publishing $(node -p "require('./$dir/package.json').name")..."
            cd "$dir"
            npm publish --access public || true
            cd "$GITHUB_WORKSPACE"
          done

      - name: Sync main package version and optionalDependencies
        run: |
          VERSION="${GITHUB_REF_NAME#v}"
          node -e "
            const pkg = require('./package.json');
            pkg.version = '${VERSION}';
            for (const dep of Object.keys(pkg.optionalDependencies || {})) {
              pkg.optionalDependencies[dep] = '${VERSION}';
            }
            require('fs').writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n');
          "

      - name: Publish main package
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: npm publish

  publish-crate:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Publish to crates.io
        run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
