name: Release

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to release (e.g., v1.2.3)'
        required: true
        type: string
      prerelease:
        description: 'Mark as pre-release'
        type: boolean
        required: false
        default: false
      draft:
        description: 'Create as draft release'
        type: boolean
        required: false
        default: false

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  # Validate release version and setup
  validate-release:
    name: Validate Release
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.version.outputs.version }}
      tag: ${{ steps.version.outputs.tag }}
      nushell-version: ${{ steps.nushell.outputs.version }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0

      - name: Determine version
        id: version
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            VERSION="${{ github.event.inputs.version }}"
          else
            VERSION="${{ github.ref_name }}"
          fi

          echo "version=${VERSION#v}" >> $GITHUB_OUTPUT
          echo "tag=${VERSION}" >> $GITHUB_OUTPUT
          echo "Release version: ${VERSION}"

      - name: Install Nushell
        uses: hustcer/setup-nu@v3
        with:
          version: '0.107.1'

      - name: Validate nushell version
        id: nushell
        run: |
          echo "Validating nushell version consistency..."
          nu scripts/check_version.nu --quiet || {
            echo "Version mismatch detected, attempting fix..."
            nu scripts/check_version.nu --fix
          }
          echo "version=0.107.1" >> $GITHUB_OUTPUT

      - name: Check for existing release
        run: |
          if gh release view "${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
            echo "❌ Release ${{ steps.version.outputs.tag }} already exists"
            exit 1
          fi
          echo "✅ Release tag is available"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Validate changelog
        run: |
          if [ -f "CHANGELOG.md" ]; then
            if grep -q "${{ steps.version.outputs.version }}" CHANGELOG.md; then
              echo "✅ Changelog entry found for version ${{ steps.version.outputs.version }}"
            else
              echo "⚠️ No changelog entry found for version ${{ steps.version.outputs.version }}"
            fi
          else
            echo "⚠️ No CHANGELOG.md file found"
          fi

  # Cross-platform release builds
  build-release:
    name: Build Release (${{ matrix.target }})
    runs-on: ${{ matrix.os }}
    needs: validate-release
    strategy:
      fail-fast: false
      matrix:
        include:
          # Linux builds
          - target: linux-amd64
            os: ubuntu-latest
            rust-target: x86_64-unknown-linux-gnu
            cross-compile: false
          - target: linux-arm64
            os: ubuntu-latest
            rust-target: aarch64-unknown-linux-gnu
            cross-compile: true

          # macOS builds
          - target: darwin-amd64
            os: macos-13
            rust-target: x86_64-apple-darwin
            cross-compile: false
          - target: darwin-arm64
            os: macos-latest
            rust-target: aarch64-apple-darwin
            cross-compile: false

          # Windows builds
          - target: windows-amd64
            os: windows-latest
            rust-target: x86_64-pc-windows-msvc
            cross-compile: false

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.rust-target }}
          components: rustfmt, clippy

      - name: Install Nushell
        uses: hustcer/setup-nu@v3
        with:
          version: ${{ needs.validate-release.outputs.nushell-version }}

      - name: Set up cross-compilation (Linux ARM64)
        if: matrix.cross-compile && matrix.target == 'linux-arm64'
        run: |
          sudo apt-get update
          sudo apt-get install -y gcc-aarch64-linux-gnu
          echo "CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
          echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV

      - name: Cache Cargo dependencies
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: release-${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            release-${{ runner.os }}-${{ matrix.target }}-cargo-
            ${{ runner.os }}-${{ matrix.target }}-cargo-

      - name: Build release binaries
        run: |
          echo "Building release binaries for ${{ matrix.target }}..."
          if [ "${{ matrix.cross-compile }}" = "true" ]; then
            nu scripts/build_cross.nu --targets ${{ matrix.target }} --verbose
          else
            nu scripts/build_all.nu --target ${{ matrix.rust-target }} --verbose
          fi
        shell: bash

      - name: Run tests (native only)
        if: "!matrix.cross-compile"
        run: |
          echo "Running tests for ${{ matrix.target }}..."
          for plugin in nu_plugin_*; do
            if [ -d "$plugin" ]; then
              echo "Testing $plugin..."
              cd "$plugin"
              cargo test --target ${{ matrix.rust-target }} --release
              cd ..
            fi
          done
        shell: bash

      - name: Collect and package release artifacts
        run: |
          echo "Collecting release artifacts for ${{ matrix.target }}..."
          nu scripts/collect_install.nu --platform ${{ matrix.target }} --force

          echo "Creating release package..."
          nu scripts/pack_dist.nu --platform ${{ matrix.target }} --force --checksums
        shell: bash

      - name: Upload release artifacts
        uses: actions/upload-artifact@v4
        with:
          name: release-${{ matrix.target }}
          path: |
            bin_archives/*${{ matrix.target }}*
          retention-days: 30

  # Create GitHub release
  create-release:
    name: Create GitHub Release
    runs-on: ubuntu-latest
    needs: [validate-release, build-release]
    permissions:
      contents: write
    outputs:
      upload_url: ${{ steps.create_release.outputs.upload_url }}
      release_id: ${{ steps.create_release.outputs.id }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install Nushell
        uses: hustcer/setup-nu@v3
        with:
          version: ${{ needs.validate-release.outputs.nushell-version }}

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

      - name: Organize release assets
        run: |
          echo "Organizing release assets..."
          mkdir -p release-assets

          # Copy all archives to release assets
          find release-artifacts/ -name "*.tar.gz" -o -name "*.zip" | while read file; do
            cp "$file" release-assets/
          done

          # Copy checksums
          find release-artifacts/ -name "checksums.txt" | head -1 | while read file; do
            cp "$file" release-assets/checksums.txt
          done

          echo "Release assets:"
          ls -la release-assets/

      - name: Generate release notes
        id: release_notes
        run: |
          echo "Generating release notes..."

          # Extract changelog for this version if available
          RELEASE_NOTES="## Nushell Plugins ${{ needs.validate-release.outputs.version }}

          ### Changes in this Release
          "

          if [ -f "CHANGELOG.md" ]; then
            # Try to extract changelog section for this version
            awk "/^## \[?${{ needs.validate-release.outputs.version }}\]?/,/^## \[?[0-9]/" CHANGELOG.md | head -n -1 | tail -n +2 >> release_notes.md || true
          fi

          # Add generic content if no specific changelog found
          if [ ! -s release_notes.md ]; then
            cat >> release_notes.md << 'EOF'
          This release includes the latest versions of all nushell plugins with bug fixes and improvements.

          ### Installation

          #### Quick Install (Unix-like systems)
          ```bash
          curl -L https://github.com/${{ github.repository }}/releases/download/${{ needs.validate-release.outputs.tag }}/install.sh | sh
          ```

          #### Manual Install
          1. Download the appropriate archive for your platform
          2. Extract the archive
          3. Run the installation script: `nu install_nu_plugins.nu`

          ### Platform Support
          - **Linux**: x86_64 (amd64) and ARM64
          - **macOS**: Intel (x86_64) and Apple Silicon (ARM64)
          - **Windows**: x86_64 (amd64)

          ### Available Plugins
          - `nu_plugin_clipboard` - Clipboard integration
          - `nu_plugin_desktop_notifications` - Desktop notifications
          - `nu_plugin_hashes` - Hashing utilities
          - `nu_plugin_highlight` - Syntax highlighting
          - `nu_plugin_image` - Image processing
          - `nu_plugin_kcl` - KCL configuration language support
          - `nu_plugin_port_extension` - Port utilities
          - `nu_plugin_qr_maker` - QR code generation
          - `nu_plugin_tera` - Tera templating

          ### Verification
          All release assets include SHA256 checksums. Verify downloads using:
          ```bash
          sha256sum -c checksums.txt
          ```
          EOF
          fi

          cat release_notes.md

          # Set output for use in create-release step
          echo "RELEASE_NOTES<<EOF" >> $GITHUB_ENV
          cat release_notes.md >> $GITHUB_ENV
          echo "EOF" >> $GITHUB_ENV

      - name: Create GitHub release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ needs.validate-release.outputs.tag }}
          release_name: Nushell Plugins ${{ needs.validate-release.outputs.version }}
          body: ${{ env.RELEASE_NOTES }}
          draft: ${{ github.event.inputs.draft == 'true' }}
          prerelease: ${{ github.event.inputs.prerelease == 'true' }}

      - name: Upload release assets
        run: |
          echo "Uploading release assets..."
          for asset in release-assets/*; do
            if [ -f "$asset" ]; then
              echo "Uploading $(basename "$asset")..."
              gh release upload "${{ needs.validate-release.outputs.tag }}" "$asset"
            fi
          done
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  # Post-release actions
  post-release:
    name: Post-Release Actions
    runs-on: ubuntu-latest
    needs: [validate-release, create-release]
    if: always() && needs.create-release.result == 'success'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Notify success
        run: |
          echo "🎉 Release ${{ needs.validate-release.outputs.version }} created successfully!"
          echo "📦 Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ needs.validate-release.outputs.tag }}"

      - name: Update installation documentation
        run: |
          echo "Consider updating:"
          echo "- README.md with new version information"
          echo "- Installation instructions"
          echo "- Compatibility matrix"

      - name: Create follow-up issue for next release
        if: "!contains(needs.validate-release.outputs.version, 'rc') && !contains(needs.validate-release.outputs.version, 'beta')"
        run: |
          NEXT_VERSION=$(echo "${{ needs.validate-release.outputs.version }}" | awk -F. '{print $1"."($2+1)".0"}')
          echo "Consider creating planning issue for next release: v$NEXT_VERSION"