name: CI

on:
  push:
    branches: [main]
    paths-ignore:
      - "**.md"
      - "docs/**"
      - "CHANGELOG.md"
  pull_request:
    branches: [main]
    paths-ignore:
      - "**.md"
      - "docs/**"
      - "CHANGELOG.md"

permissions:
  contents: read

concurrency:
  group: ci-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    name: Test Suite
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

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

      - name: Cache cargo registry
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-

      - name: Check formatting
        run: cargo fmt -- --check

      - name: Run clippy
        run: cargo clippy --lib --tests -- -D warnings -A clippy::too_many_arguments -A clippy::items-after-test-module -A clippy::type-complexity -A clippy::should-implement-trait -A renamed_and_removed_lints -A clippy::collapsible-if -A clippy::len-zero -A clippy::assertions-on-constants -A dead-code

      - name: Install cargo-audit
        run: |
          if ! command -v cargo-audit &> /dev/null; then
            cargo install cargo-audit --locked
          fi

      - name: Run cargo-audit (CVE scan)
        run: cargo audit --ignore RUSTSEC-2024-0436

      - name: Run tests
        run: cargo test --lib --tests

  build:
    name: Build ${{ matrix.name }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            name: Linux (gnu)
            target: x86_64-unknown-linux-gnu

          - os: ubuntu-latest
            name: Linux (musl)
            target: x86_64-unknown-linux-musl

          - os: macos-latest
            name: macOS
            target: aarch64-apple-darwin
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

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

      - name: Install musl tools (Linux)
        if: matrix.target == 'x86_64-unknown-linux-musl'
        run: |
          sudo apt-get update
          sudo apt-get install -y musl-tools musl-dev

      - name: Cache cargo registry
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.target }}-cargo-

      - name: Build (musl with vendored OpenSSL)
        if: matrix.target == 'x86_64-unknown-linux-musl'
        run: cargo build --release --target ${{ matrix.target }} --features vendored-openssl

      - name: Build (other targets)
        if: matrix.target != 'x86_64-unknown-linux-musl'
        run: cargo build --release --target ${{ matrix.target }}

      - name: Upload artifacts
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
        with:
          name: flux9s-${{ matrix.name }}
          path: |
            target/${{ matrix.target }}/release/flux9s
            target/${{ matrix.target }}/release/flux9s.exe

  build-windows:
    name: Build Windows
    if: ${{ github.event_name == 'push' }}
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: x86_64-pc-windows-msvc

      - name: Install OpenSSL (Windows)
        run: |
          vcpkg install openssl:x64-windows-static-md
          echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" >> $env:GITHUB_ENV
          echo "OPENSSL_DIR=$env:VCPKG_INSTALLATION_ROOT\packages\openssl_x64-windows-static-md" >> $env:GITHUB_ENV

      - name: Cache cargo registry
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ runner.os }}-x86_64-pc-windows-msvc-cargo-${{ hashFiles('Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-x86_64-pc-windows-msvc-cargo-

      - name: Build
        run: cargo build --release --target x86_64-pc-windows-msvc

      - name: Upload artifacts
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
        with:
          name: flux9s-Windows
          path: target/x86_64-pc-windows-msvc/release/flux9s.exe
