name: Build and Test

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]
  workflow_dispatch:
    inputs:
      targets:
        description: 'Comma-separated list of targets to build (e.g., linux-amd64,darwin-arm64)'
        required: false
        default: 'host'
      test:
        description: 'Run tests'
        type: boolean
        required: false
        default: true

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  # Job to validate nushell version consistency
  validate:
    name: Validate Setup
    runs-on: ubuntu-latest
    outputs:
      nushell-version: ${{ steps.version.outputs.version }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: recursive

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

      - name: Validate nushell version
        id: version
        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 repository structure
        run: |
          echo "Checking repository structure..."
          ls -la
          echo "Plugin directories:"
          ls -d nu_plugin_* || echo "No plugin directories found"
          echo "Configuration files:"
          ls -la etc/ || echo "No etc directory found"

  # Build matrix for different platforms
  build:
    name: Build (${{ matrix.target }})
    runs-on: ${{ matrix.os }}
    needs: validate
    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  # Intel macOS
            rust-target: x86_64-apple-darwin
            cross-compile: false
          - target: darwin-arm64
            os: macos-latest  # Apple Silicon
            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.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: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.target }}-cargo-
            ${{ runner.os }}-cargo-

      - name: Check code formatting
        run: |
          echo "Checking code formatting..."
          nu scripts/run.sh format_check.nu || {
            echo "Code formatting check failed. Run 'just fmt' to fix."
            exit 1
          }

      - name: Run Clippy linting
        run: |
          echo "Running Clippy linting..."
          for plugin in nu_plugin_*; do
            if [ -d "$plugin" ]; then
              echo "Linting $plugin..."
              cd "$plugin"
              cargo clippy --target ${{ matrix.rust-target }} -- -D warnings
              cd ..
            fi
          done
        shell: bash

      - name: Build plugins
        run: |
          echo "Building plugins 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
        if: github.event.inputs.test != 'false' && !matrix.cross-compile
        run: |
          echo "Running tests..."
          for plugin in nu_plugin_*; do
            if [ -d "$plugin" ]; then
              echo "Testing $plugin..."
              cd "$plugin"
              cargo test --target ${{ matrix.rust-target }}
              cd ..
            fi
          done
        shell: bash

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

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

      - name: Upload build logs
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: build-logs-${{ matrix.target }}
          path: |
            target/*/build/*/out
            target/*/build/*/stderr
          retention-days: 7

  # Security audit
  audit:
    name: Security Audit
    runs-on: ubuntu-latest
    needs: validate
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Install cargo-audit
        run: cargo install cargo-audit

      - name: Run security audit
        run: |
          echo "Running security audit..."
          for plugin in nu_plugin_*; do
            if [ -d "$plugin" ]; then
              echo "Auditing $plugin..."
              cd "$plugin"
              cargo audit
              cd ..
            fi
          done

  # Collect and package results
  package:
    name: Package Results
    runs-on: ubuntu-latest
    needs: [validate, build]
    if: github.event_name != 'pull_request'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

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

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

      - name: Organize artifacts
        run: |
          echo "Organizing build artifacts..."
          mkdir -p distribution
          for artifact in artifacts/plugins-*; do
            if [ -d "$artifact" ]; then
              target=$(basename "$artifact" | sed 's/plugins-//')
              echo "Processing $target..."
              cp -r "$artifact"/* distribution/
            fi
          done

      - name: Create packages
        run: |
          echo "Creating distribution packages..."
          nu scripts/pack_dist.nu --all-platforms --force --checksums

      - name: Upload packages
        uses: actions/upload-artifact@v4
        with:
          name: distribution-packages
          path: |
            bin_archives/
          retention-days: 90

  # Quality gate
  quality-gate:
    name: Quality Gate
    runs-on: ubuntu-latest
    needs: [build, audit]
    if: always()
    steps:
      - name: Check build results
        run: |
          echo "Build results:"
          echo "Build status: ${{ needs.build.result }}"
          echo "Audit status: ${{ needs.audit.result }}"

          if [ "${{ needs.build.result }}" != "success" ]; then
            echo "❌ Build failed"
            exit 1
          fi

          if [ "${{ needs.audit.result }}" != "success" ]; then
            echo "⚠️ Security audit failed"
            # Don't fail the build for audit issues, but warn
          fi

          echo "✅ Quality gate passed"

      - name: Report status
        if: always()
        run: |
          if [ "${{ job.status }}" = "success" ]; then
            echo "🎉 All checks passed!"
          else
            echo "❌ Some checks failed"
          fi