name: CI

on:
  push:
    branches: [ main, master, develop ]
  pull_request:
    branches: [ main, master, develop ]
  schedule:
    # Run at 2 AM UTC every Monday
    - cron: '0 2 * * 1'

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  test:
    name: Test Suite
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        rust:
          - stable
          - beta
          - nightly
        exclude:
          # Skip beta and nightly on Windows to reduce CI time
          - os: windows-latest
            rust: beta
          - os: windows-latest
            rust: nightly

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

      - name: Setup build environment
        uses: ./.github/actions/setup-build
        with:
          rust-toolchain: ${{ matrix.rust }}
          rust-components: rustfmt, clippy
          cache-key-prefix: cargo-${{ matrix.rust }}

      - name: Download test models
        run: just download-test-model

      - name: Build with platform-specific features
        run: just check

      - name: Run unit tests
        run: just test-unit

      - name: Run integration tests
        run: just test-integration

      - name: Run concurrency tests
        run: just test-concurrency

      - name: Build documentation
        run: just doc
        env:
          RUSTDOCFLAGS: -D warnings

      - name: Check without default features
        run: cargo check --verbose --no-default-features

      - name: Check with server feature
        run: just check-server

      - name: Check backend features compilation
        run: just check-backends

  fmt:
    name: Rustfmt
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

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

      - name: Install just
        uses: taiki-e/install-action@just

      - name: Check formatting
        run: just fmtcheck

  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup build environment
        uses: ./.github/actions/setup-build
        with:
          rust-components: clippy
          cache-key-prefix: cargo-clippy

      - name: Run clippy
        run: just clippy

  security:
    name: Security Audit
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

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

      - name: Run security audit
        run: cargo audit

  coverage-unit:
    name: Code Coverage (Unit Tests)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup build environment
        uses: ./.github/actions/setup-build
        with:
          cache-key-prefix: cargo-coverage

      - name: Install tarpaulin
        run: cargo install cargo-tarpaulin

      - name: Generate unit test coverage
        run: cargo tarpaulin --lib --features openmp

      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3
        with:
          file: ./cobertura.xml
          flags: unittests
          name: codecov-umbrella
          fail_ci_if_error: false

  coverage-integration:
    name: Integration Tests (Release Mode)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup build environment
        uses: ./.github/actions/setup-build
        with:
          cache-key-prefix: cargo-integration

      - name: Download test models
        run: just download-test-model

      - name: Run integration tests in release mode
        run: |
          export EMBELLAMA_TEST_MODEL=$(pwd)/models/test/all-minilm-l6-v2-q4_k_m.gguf
          cargo test --release --features openmp --tests --workspace
        timeout-minutes: 20

  msrv:
    name: Minimum Supported Rust Version
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup build environment
        uses: ./.github/actions/setup-build
        with:
          rust-toolchain: '1.88.0'
          cache-key-prefix: cargo-msrv

      - name: Check MSRV
        run: just check

  publish-dry-run:
    name: Publish Dry Run
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup build environment
        uses: ./.github/actions/setup-build
        with:
          install-just: 'false'  # Don't need just for publishing
          cache-key-prefix: cargo-publish

      - name: Dry run publish
        run: cargo publish --dry-run

  server-tests:
    name: Server Tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup build environment
        uses: ./.github/actions/setup-build
        with:
          cache-key-prefix: cargo-server

      - name: Download test models
        run: just download-test-model

      - name: Check server compilation
        run: just check-server

      - name: Run server integration tests
        run: just test-server-integration

      - name: Run OpenAI compatibility tests
        run: just test-server-compat

      - name: Run server load tests
        run: just test-server-load
