name: Coverage

on:
  push:
    branches: [develop, main]
    paths-ignore:
      - '**.md'
      - 'docs/**'
      - 'LICENSE'
      - '.gitignore'
      - '.gitattributes'
  pull_request:
    paths-ignore:
      - '**.md'
      - 'docs/**'
      - 'LICENSE'
      - '.gitignore'
      - '.gitattributes'
  workflow_dispatch:

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

permissions:
  contents: read
  pull-requests: write

env:
  CARGO_TERM_COLOR: always
  CARGO_INCREMENTAL: 0
  RUST_BACKTRACE: 1

jobs:
  coverage:
    name: Code Coverage
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v6
        with:
          persist-credentials: false
          fetch-depth: 1

      - uses: dtolnay/rust-toolchain@stable
        with:
          components: llvm-tools-preview

      - uses: Swatinem/rust-cache@v2
        with:
          cache-on-failure: true

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

      - name: Run coverage
        run: cargo llvm-cov --all-targets --codecov --output-path codecov.json

      - name: Generate summary
        run: cargo llvm-cov --all-targets --summary-only 2>&1 | tee coverage-summary.txt

      - name: Check coverage threshold
        run: |
          # Extract total line coverage percentage
          TOTAL_LINE=$(tail -1 coverage-summary.txt | awk '{for(i=1;i<=NF;i++) if($i ~ /^[0-9]+\.[0-9]+%$/ && ++n==4) {gsub(/%/,"",$i); print $i; exit}}')
          echo "Total line coverage: ${TOTAL_LINE}%"

          # Advisory threshold — warn but don't fail
          THRESHOLD=50
          if [ "$(echo "$TOTAL_LINE < $THRESHOLD" | bc -l)" -eq 1 ]; then
            echo "::warning::Line coverage ${TOTAL_LINE}% is below advisory threshold of ${THRESHOLD}%"
          else
            echo "Coverage ${TOTAL_LINE}% meets advisory threshold of ${THRESHOLD}%"
          fi

      - name: Post coverage to PR
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const summary = fs.readFileSync('coverage-summary.txt', 'utf8');

            // Extract the table (last lines with the data)
            const lines = summary.trim().split('\n');
            const dataLines = lines.filter(l => l.includes('%') || l.includes('---') || l.includes('Filename'));

            const body = `## Code Coverage Report

            \`\`\`
            ${dataLines.join('\n')}
            \`\`\`

            *Generated by [cargo-llvm-cov](https://github.com/taiki-e/cargo-llvm-cov)*`;

            // Find existing coverage comment
            const { data: comments } = await github.rest.issues.listComments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
            });
            const existing = comments.find(c => c.body.includes('Code Coverage Report'));

            if (existing) {
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: existing.id,
                body,
              });
            } else {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.issue.number,
                body,
              });
            }
