name: Release - Build & Distribute Bundles

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to build (e.g., 0.1.0)'
        required: true
        type: string
      targets:
        description: 'Targets to build (comma-separated, or "all")'
        required: false
        default: 'all'
        type: string

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  prepare:
    name: Prepare Release
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.version.outputs.version }}
      tag: ${{ steps.version.outputs.tag }}
    steps:
      - name: Determine version
        id: version
        run: |
          if [[ "${{ github.ref }}" == refs/tags/* ]]; then
            VERSION="${{ github.ref_name }}"
            VERSION="${VERSION#v}"
          else
            VERSION="${{ inputs.version }}"
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "tag=v$VERSION" >> $GITHUB_OUTPUT
          echo "Building release: $VERSION"

  build-matrix:
    name: Build for ${{ matrix.target }}
    needs: prepare
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          # Linux x86_64 (glibc)
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            artifact_name: syntaxis-x86_64-linux
            use_cross: false

          # Linux ARM64 (glibc)
          - os: ubuntu-latest
            target: aarch64-unknown-linux-gnu
            artifact_name: syntaxis-aarch64-linux
            use_cross: true

          # macOS Intel (x86_64)
          - os: macos-latest
            target: x86_64-apple-darwin
            artifact_name: syntaxis-x86_64-macos
            use_cross: false

          # macOS ARM64 (Apple Silicon)
          - os: macos-latest
            target: aarch64-apple-darwin
            artifact_name: syntaxis-aarch64-macos
            use_cross: false

          # Windows x86_64
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            artifact_name: syntaxis-x86_64-windows
            use_cross: false

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

      - name: Setup Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Setup cross (for ARM builds)
        if: matrix.use_cross
        run: cargo install cross

      - name: Cache cargo registry
        uses: actions/cache@v3
        with:
          path: ~/.cargo/registry
          key: cargo-registry-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}

      - name: Cache cargo index
        uses: actions/cache@v3
        with:
          path: ~/.cargo/git
          key: cargo-git-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}

      - name: Cache cargo build
        uses: actions/cache@v3
        with:
          path: target
          key: cargo-build-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}

      - name: Build binaries
        run: |
          if [[ "${{ matrix.use_cross }}" == "true" ]]; then
            cross build --release --target ${{ matrix.target }} \
              --workspace \
              --exclude syntaxis-dashboard
          else
            cargo build --release --target ${{ matrix.target }} \
              --workspace \
              --exclude syntaxis-dashboard
          fi
        shell: bash

      - name: Create bundle directory
        run: |
          mkdir -p dist
          mkdir -p bundles
        shell: bash

      - name: Prepare bundle artifacts
        run: |
          TARGET_DIR="target/${{ matrix.target }}/release"
          BUNDLE_NAME="${{ matrix.artifact_name }}-v${{ needs.prepare.outputs.version }}"
          BUNDLE_DIR="bundles/$BUNDLE_NAME"

          mkdir -p "$BUNDLE_DIR/bin"
          mkdir -p "$BUNDLE_DIR/configs"
          mkdir -p "$BUNDLE_DIR/docs"

          # Copy binaries (with platform-specific extension)
          if [[ "${{ runner.os }}" == "Windows" ]]; then
            cp "$TARGET_DIR/syntaxis-cli.exe" "$BUNDLE_DIR/bin/" || true
            cp "$TARGET_DIR/syntaxis-tui.exe" "$BUNDLE_DIR/bin/" || true
            cp "$TARGET_DIR/syntaxis-api.exe" "$BUNDLE_DIR/bin/" || true
          else
            cp "$TARGET_DIR/syntaxis-cli" "$BUNDLE_DIR/bin/" || true
            cp "$TARGET_DIR/syntaxis-tui" "$BUNDLE_DIR/bin/" || true
            cp "$TARGET_DIR/syntaxis-api" "$BUNDLE_DIR/bin/" || true
          fi

          # Copy configs
          cp configs/provisioning.toml "$BUNDLE_DIR/configs/" || true
          cp configs/database-default.toml "$BUNDLE_DIR/configs/" || true
          cp -r configs/cli "$BUNDLE_DIR/configs/" || true
          cp -r configs/tui "$BUNDLE_DIR/configs/" || true
          cp -r configs/api "$BUNDLE_DIR/configs/" || true

          # Copy docs
          cp README.md "$BUNDLE_DIR/docs/" || true
          cp CLAUDE.md "$BUNDLE_DIR/docs/" || true

          # Copy installer script
          cp scripts/provisioning/install.sh "$BUNDLE_DIR/" || true
          chmod +x "$BUNDLE_DIR/install.sh" || true

          echo "Bundle prepared: $BUNDLE_DIR"
          ls -la "$BUNDLE_DIR/bin/" || true
        shell: bash

      - name: Generate manifest
        run: |
          BUNDLE_NAME="${{ matrix.artifact_name }}-v${{ needs.prepare.outputs.version }}"
          BUNDLE_DIR="bundles/$BUNDLE_NAME"
          TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

          cat > "$BUNDLE_DIR/manifest.toml" << EOF
          [bundle]
          version = "${{ needs.prepare.outputs.version }}"
          target = "${{ matrix.target }}"
          created_at = "$TIMESTAMP"
          format = "tar.gz"

          [artifacts]
          binaries = ["syntaxis-cli", "syntaxis-tui", "syntaxis-api"]
          configs = ["provisioning.toml", "database-default.toml"]
          docs = ["README.md", "CLAUDE.md"]

          [checksums]
          EOF

          # Add checksums for binaries
          cd "$BUNDLE_DIR/bin"
          for binary in *; do
            if [[ -f "$binary" ]]; then
              if command -v sha256sum &> /dev/null; then
                CHECKSUM=$(sha256sum "$binary" | awk '{print $1}')
              else
                CHECKSUM=$(shasum -a 256 "$binary" | awk '{print $1}')
              fi
              echo "\"bin/$binary\" = \"$CHECKSUM\"" >> ../manifest.toml
            fi
          done
        shell: bash

      - name: Create archive (tar.gz for Unix)
        if: runner.os != 'Windows'
        run: |
          cd bundles
          BUNDLE_NAME="${{ matrix.artifact_name }}-v${{ needs.prepare.outputs.version }}"
          tar -czf "../dist/${BUNDLE_NAME}.tar.gz" "$BUNDLE_NAME"
          echo "Created: dist/${BUNDLE_NAME}.tar.gz"
        shell: bash

      - name: Create archive (zip for Windows)
        if: runner.os == 'Windows'
        run: |
          cd bundles
          $BUNDLE_NAME = "${{ matrix.artifact_name }}-v${{ needs.prepare.outputs.version }}"
          Compress-Archive -Path $BUNDLE_NAME -DestinationPath "..\dist\${BUNDLE_NAME}.zip"
          Write-Output "Created: dist/${BUNDLE_NAME}.zip"
        shell: pwsh

      - name: Generate checksums
        run: |
          cd dist
          if command -v sha256sum &> /dev/null; then
            sha256sum * > SHA256SUMS
          else
            shasum -a 256 * > SHA256SUMS
          fi
          cat SHA256SUMS
        shell: bash

      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: bundle-${{ matrix.target }}
          path: dist/*
          retention-days: 30

  create-release:
    name: Create GitHub Release
    needs: [prepare, build-matrix]
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/')
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

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

      - name: Prepare release files
        run: |
          mkdir -p release
          find release-artifacts -type f -name "*.tar.gz" -o -name "*.zip" -o -name "SHA256SUMS" | while read file; do
            cp "$file" release/
          done

          # Combine all checksums
          cat release-artifacts/*/SHA256SUMS > release/SHA256SUMS 2>/dev/null || true

          ls -lah release/
        shell: bash

      - name: Create Release Notes
        run: |
          cat > RELEASE_NOTES.md << 'EOF'
          # syntaxis v${{ needs.prepare.outputs.version }}

          ## Download

          Pre-built binaries for multiple platforms:

          | Platform | File | SHA256 |
          |----------|------|--------|
          | Linux x86_64 | [syntaxis-x86_64-linux-v${{ needs.prepare.outputs.version }}.tar.gz](./releases/download/${{ needs.prepare.outputs.tag }}/syntaxis-x86_64-linux-v${{ needs.prepare.outputs.version }}.tar.gz) | Check SHA256SUMS |
          | macOS Intel | [syntaxis-x86_64-macos-v${{ needs.prepare.outputs.version }}.tar.gz](./releases/download/${{ needs.prepare.outputs.tag }}/syntaxis-x86_64-macos-v${{ needs.prepare.outputs.version }}.tar.gz) | Check SHA256SUMS |
          | macOS ARM64 | [syntaxis-aarch64-macos-v${{ needs.prepare.outputs.version }}.tar.gz](./releases/download/${{ needs.prepare.outputs.tag }}/syntaxis-aarch64-macos-v${{ needs.prepare.outputs.version }}.tar.gz) | Check SHA256SUMS |
          | Linux ARM64 | [syntaxis-aarch64-linux-v${{ needs.prepare.outputs.version }}.tar.gz](./releases/download/${{ needs.prepare.outputs.tag }}/syntaxis-aarch64-linux-v${{ needs.prepare.outputs.version }}.tar.gz) | Check SHA256SUMS |
          | Windows x86_64 | [syntaxis-x86_64-windows-v${{ needs.prepare.outputs.version }}.zip](./releases/download/${{ needs.prepare.outputs.tag }}/syntaxis-x86_64-windows-v${{ needs.prepare.outputs.version }}.zip) | Check SHA256SUMS |

          ## Installation

          ### Quick Install (Offline Bundle)

          1. Download the appropriate bundle for your platform
          2. Extract: `tar -xzf bundle.tar.gz` or `unzip bundle.zip`
          3. Install: `cd bundle && ./install.sh`

          ### Verify Integrity

          ```bash
          # Download checksums
          curl -O https://github.com/syntaxis/syntaxis/releases/download/${{ needs.prepare.outputs.tag }}/SHA256SUMS

          # Verify bundles
          sha256sum -c SHA256SUMS
          ```

          ## What's Included

          Each bundle contains:
          - ✅ Compiled binaries: `syntaxis-cli`, `syntaxis-tui`, `syntaxis-api`
          - ✅ Configuration files: provisioning.toml, database configs, feature configs
          - ✅ Documentation: README, CLAUDE.md, installation guide
          - ✅ Offline installer: install.sh for systems without NuShell
          - ✅ SHA256 checksums for integrity verification

          ## Changelog

          See [CHANGELOG.md](./CHANGELOG.md) for detailed changes in this release.

          ## Support

          - 📖 Documentation: https://github.com/syntaxis/syntaxis/blob/main/README.md
          - 🐛 Issues: https://github.com/syntaxis/syntaxis/issues
          - 💬 Discussions: https://github.com/syntaxis/syntaxis/discussions
          EOF
          cat RELEASE_NOTES.md
        shell: bash

      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          files: release/*
          body_path: RELEASE_NOTES.md
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  publish-docs:
    name: Publish Documentation
    needs: [prepare, create-release]
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/')
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Pages
        uses: actions/configure-pages@v3

      - name: Build documentation site
        run: |
          mkdir -p site

          # Copy main docs
          cp README.md site/index.md
          cp CLAUDE.md site/CLAUDE.md
          cp scripts/provisioning/README.md site/PROVISIONING.md

          # Create release index
          cat > site/releases.md << 'EOF'
          # Releases

          ## Latest Release: v${{ needs.prepare.outputs.version }}

          [Download from GitHub Releases](https://github.com/syntaxis/syntaxis/releases/tag/${{ needs.prepare.outputs.tag }})

          All releases include:
          - Pre-built binaries for Linux, macOS, and Windows
          - Complete configuration files
          - Offline documentation
          - Installation scripts
          - SHA256 checksums for integrity verification
          EOF

          ls -la site/
        shell: bash

      - name: Upload Pages artifact
        uses: actions/upload-pages-artifact@v2
        with:
          path: 'site'

  deploy-pages:
    name: Deploy GitHub Pages
    needs: publish-docs
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/')
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Deploy to Pages
        id: deployment
        uses: actions/deploy-pages@v2

  notify:
    name: Release Notification
    needs: [prepare, create-release]
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/')
    steps:
      - name: Release Summary
        run: |
          cat << 'EOF'
          ╔════════════════════════════════════════════════════════╗
          ║  syntaxis v${{ needs.prepare.outputs.version }} Released  ║
          ╚════════════════════════════════════════════════════════╝

          ✅ Build completed for all platforms:
             • Linux x86_64 (glibc)
             • Linux ARM64 (glibc)
             • macOS x86_64 (Intel)
             • macOS ARM64 (Apple Silicon)
             • Windows x86_64 (MSVC)

          📦 Bundles created with:
             • Compiled binaries
             • Configuration files
             • Documentation
             • Installation scripts

          🔗 GitHub Release: https://github.com/syntaxis/syntaxis/releases/tag/${{ needs.prepare.outputs.tag }}

          📖 Documentation: https://github.com/syntaxis/syntaxis

          🚀 Installation:
             1. Download bundle for your platform
             2. Extract: tar -xzf bundle.tar.gz
             3. Install: cd bundle && ./install.sh
          EOF
        shell: bash
