name: Code Coverage

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]
  schedule:
    # Run daily at 2 AM UTC
    - cron: '0 2 * * *'
  workflow_dispatch:

jobs:
  coverage:
    name: Generate Coverage Report
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_DB: colaflow_test
          POSTGRES_USER: colaflow_test
          POSTGRES_PASSWORD: colaflow_test_password
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

      redis:
        image: redis:7-alpine
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 3s
          --health-retries 5
        ports:
          - 6379:6379

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup .NET 9
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '9.0.x'

      - name: Restore dependencies
        run: dotnet restore
        working-directory: ./src

      - name: Build solution
        run: dotnet build --no-restore --configuration Release
        working-directory: ./src

      - name: Run tests with coverage
        run: |
          dotnet test \
            --no-build \
            --configuration Release \
            --logger "console;verbosity=minimal" \
            /p:CollectCoverage=true \
            /p:CoverletOutputFormat=opencover \
            /p:CoverletOutput=./coverage/ \
            /p:ExcludeByFile="**/*.g.cs,**/*.Designer.cs,**/Migrations/**" \
            /p:Exclude="[*.Tests]*"
        working-directory: ./tests
        env:
          ConnectionStrings__DefaultConnection: "Host=localhost;Port=5432;Database=colaflow_test;Username=colaflow_test;Password=colaflow_test_password"
          ConnectionStrings__Redis: "localhost:6379"

      - name: Install ReportGenerator
        run: dotnet tool install -g dotnet-reportgenerator-globaltool

      - name: Generate detailed coverage report
        run: |
          reportgenerator \
            -reports:./tests/coverage/coverage.opencover.xml \
            -targetdir:./coverage-report \
            -reporttypes:"Html;Badges;TextSummary;MarkdownSummaryGithub;Cobertura"

      - name: Display coverage summary
        run: |
          echo "## Coverage Summary" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          cat ./coverage-report/SummaryGithub.md >> $GITHUB_STEP_SUMMARY

      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v4
        with:
          files: ./tests/coverage/coverage.opencover.xml
          flags: unittests
          name: colaflow-coverage
          fail_ci_if_error: false
        env:
          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
        continue-on-error: true

      - name: Archive coverage report
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report-${{ github.sha }}
          path: ./coverage-report
          retention-days: 90

      - name: Generate coverage badge
        run: |
          # Extract line coverage percentage
          COVERAGE=$(grep "Line coverage:" ./coverage-report/Summary.txt | awk '{print $3}' | sed 's/%//')
          echo "COVERAGE=$COVERAGE" >> $GITHUB_ENV

          # Determine badge color
          if (( $(echo "$COVERAGE >= 90" | bc -l) )); then
            COLOR="brightgreen"
          elif (( $(echo "$COVERAGE >= 80" | bc -l) )); then
            COLOR="green"
          elif (( $(echo "$COVERAGE >= 70" | bc -l) )); then
            COLOR="yellow"
          elif (( $(echo "$COVERAGE >= 60" | bc -l) )); then
            COLOR="orange"
          else
            COLOR="red"
          fi
          echo "BADGE_COLOR=$COLOR" >> $GITHUB_ENV

      - name: Create coverage badge
        uses: schneegans/dynamic-badges-action@v1.7.0
        with:
          auth: ${{ secrets.GIST_SECRET }}
          gistID: your-gist-id-here
          filename: colaflow-coverage.json
          label: Coverage
          message: ${{ env.COVERAGE }}%
          color: ${{ env.BADGE_COLOR }}
        continue-on-error: true

      - name: Check coverage threshold
        run: |
          COVERAGE=$(grep "Line coverage:" ./coverage-report/Summary.txt | awk '{print $3}' | sed 's/%//')

          echo "📊 Coverage Report"
          echo "=================="
          cat ./coverage-report/Summary.txt
          echo ""

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

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

            const comment = `## 📊 Code Coverage Report

            ${summary}

            [View detailed report in artifacts](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
            `;

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: comment
            });
