name: Code Coverage

on:
  push:
    branches: [ main, master ]
  pull_request:
    branches: [ main, master ]

env:
  CARGO_TERM_COLOR: always

jobs:
  coverage:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v6

    - name: Install Rust
      uses: actions-rs/toolchain@v1
      with:
        toolchain: stable
        override: true
        components: llvm-tools-preview

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

    - name: Cache cargo-llvm-cov
      id: cache-llvm-cov
      uses: actions/cache@v5
      with:
        path: ~/.cargo/bin/cargo-llvm-cov
        key: ${{ runner.os }}-cargo-llvm-cov-0.6.18

    - name: Install cargo-llvm-cov
      if: steps.cache-llvm-cov.outputs.cache-hit != 'true'
      run: cargo install cargo-llvm-cov

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

    - name: Free up disk space
      run: |
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /usr/local/lib/android
        sudo rm -rf /opt/ghc
        sudo rm -rf /opt/hostedtoolcache/CodeQL
        sudo docker image prune --all --force
        df -h

    - name: Generate code coverage
      run: |
        cargo llvm-cov clean
        mkdir -p target/coverage
        cargo llvm-cov nextest --all-features --json --output-path target/coverage/coverage.json
        cargo llvm-cov nextest --all-features --html --output-dir target/coverage --no-clean
        COVERAGE=$(cat target/coverage/coverage.json | jq -r '.data[0].totals.lines.percent')
        echo "Current coverage: ${COVERAGE}%"

    - name: Archive code coverage results
      uses: actions/upload-artifact@v6
      with:
        name: code-coverage-report
        path: target/coverage/

    - name: Check coverage threshold
      run: |
        COVERAGE=$(cat target/coverage/coverage.json | jq -r '.data[0].totals.lines.percent')
        echo "Current coverage: ${COVERAGE}%"

        if (( $(echo "$COVERAGE < 80" | bc -l) )); then
          echo "⚠️  Coverage is below 80%: $COVERAGE%"
          exit 1
        else
          echo "✅ Coverage meets 80% threshold: $COVERAGE%"
        fi
