name: Code Style
on:
  pull_request:

jobs:
  format:
    name: Formatting
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v6
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        components: rustfmt
    - name: Check formatting
      run: cargo fmt --all -- --check

  deny-check:
    name: cargo-deny
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v6
    - name: Run cargo deny
      uses: EmbarkStudios/cargo-deny-action@v2

  clippy:
    name: Clippy (${{ matrix.name }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: all-features
            flags: "--all-features"
          - name: default
            flags: ""
          - name: libsql-only
            flags: "--no-default-features --features libsql"
    steps:
    - name: Checkout repository
      uses: actions/checkout@v6
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        components: clippy
    - uses: Swatinem/rust-cache@v2
      with:
        key: clippy-${{ matrix.name }}
    - name: Check lints
      run: cargo clippy --all --benches --tests --examples ${{ matrix.flags }} -- -D warnings

  clippy-windows:
    name: Clippy Windows (${{ matrix.name }})
    if: github.base_ref == 'main'
    runs-on: windows-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: all-features
            flags: "--all-features"
          - name: default
            flags: ""
          - name: libsql-only
            flags: "--no-default-features --features libsql"
    steps:
    - name: Checkout repository
      uses: actions/checkout@v6
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        components: clippy
    - uses: Swatinem/rust-cache@v2
      with:
        key: clippy-windows-${{ matrix.name }}
    - name: Check lints
      run: cargo clippy --all --benches --tests --examples ${{ matrix.flags }} -- -D warnings

  no-panics:
    name: No panics in production code
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v6
      with:
        fetch-depth: 0
    - uses: actions/setup-python@v5
      with:
        python-version: "3.12"
    - name: Check for .unwrap(), .expect(), assert!() in production code
      run: |
        BASE="${{ github.event.pull_request.base.sha }}"
        python3 scripts/check_no_panics.py --base "$BASE" --head HEAD

  # Roll-up job for branch protection
  code-style:
    name: Code Style (fmt + clippy + deny)
    runs-on: ubuntu-latest
    if: always()
    needs: [format, clippy, clippy-windows, deny-check, no-panics]
    steps:
      - run: |
          if [[ "${{ needs.format.result }}" != "success" || "${{ needs.clippy.result }}" != "success" || "${{ needs.deny-check.result }}" != "success" || "${{ needs.no-panics.result }}" != "success" ]]; then
            echo "One or more jobs failed"
            exit 1
          fi
          # clippy-windows only runs on main PRs, so skipped is acceptable but failure is not
          if [[ "${{ needs.clippy-windows.result }}" != "success" && "${{ needs.clippy-windows.result }}" != "skipped" ]]; then
            echo "Windows clippy failed: ${{ needs.clippy-windows.result }}"
            exit 1
          fi
