# CI Pipeline for Puhu - Python package with Rust extensions
name: CI

on:
  push:
    branches: ["main", "develop"]
  pull_request:
    branches: ["main"]

jobs:
  test:
    name: Test on ${{ matrix.os }} with Python ${{ matrix.python-version }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

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

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable

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

      - name: Cache Python dependencies
        uses: actions/cache@v3
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt', '**/pyproject.toml') }}
          restore-keys: |
            ${{ runner.os }}-pip-

      - name: Install Python dependencies
        run: |
          python -m pip install --upgrade pip
          pip install maturin pytest pytest-cov flake8 black isort
          pip install -r requirements.txt

      - name: Lint Python code with flake8
        run: |
          # Stop build on Python syntax errors or undefined names
          flake8 python/ --count --select=E9,F63,F7,F82 --show-source --statistics
          # Treat all other errors as warnings
          flake8 python/ --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

      - name: Check Python code formatting with black
        run: |
          black --check python/

      - name: Check Python import sorting with isort
        run: |
          isort --check-only python/

      # - name: Lint Rust code
      #   run: |
      #     cargo clippy -- -D warnings

      # - name: Check Rust code formatting
      #   run: |
      #     cargo fmt --check

      - name: Build and install Rust extension with maturin
        run: |
          # Install in editable mode using pip install -e .
          # This ensures maturin builds and installs properly
          pip install -e . --verbose
          # Verify installation
          python -c "import puhu; print('Puhu installed successfully')"

      - name: Run Python tests
        run: |
          pytest python/puhu/tests/ -v

  build-wheels:
    name: Build wheels on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    needs: test
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]

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

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Install cibuildwheel
        run: |
          python -m pip install --upgrade pip
          pip install cibuildwheel

      - name: Build wheels
        run: |
          python -m cibuildwheel --output-dir wheelhouse
        env:
          # Build wheels for Python 3.8-3.12
          CIBW_BUILD: "cp38-* cp39-* cp310-* cp311-* cp312-*"
          # Skip 32-bit builds and musl builds for now
          CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux_*"
          # Use maturin to build
          CIBW_BEFORE_BUILD: "pip install maturin"
          CIBW_BUILD_COMMAND: "maturin build --release --out {wheel_dir} --find-interpreter"

      - name: Upload wheels as artifacts
        uses: actions/upload-artifact@v4
        with:
          name: wheels-${{ matrix.os }}
          path: wheelhouse/*.whl

  benchmark:
    name: Performance benchmarks
    runs-on: ubuntu-latest
    needs: test
    if: github.event_name == 'pull_request'

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

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install maturin
          pip install -r requirements.txt
          pip install -r requirements_benchmark.txt

      - name: Build package
        run: |
          pip install -e . --verbose

      - name: Run benchmarks
        run: |
          python benchmark.py --iterations 5 --output-dir benchmark_results

      - name: Upload benchmark results
        uses: actions/upload-artifact@v4
        with:
          name: benchmark-results
          path: benchmark_results/
