#!/bin/bash

# Coverage Gate Local Testing Script
# This script allows testing the coverage gate logic locally

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Configuration
COVERAGE_THRESHOLD=0.5  # Maximum allowed decrease in coverage
BASE_BRANCH="main"
CURRENT_BRANCH=$(git branch --show-current)

# Function to print colored output
print_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Function to get coverage percentage
get_coverage() {
    local branch=$1
    print_info "Getting coverage for branch: $branch"
    
    # Checkout the branch
    git checkout "$branch" 2>/dev/null || {
        print_error "Failed to checkout branch: $branch"
        return 1
    }
    
    # Run tests and get coverage
    if ./scripts/run-tests.sh unit >/dev/null 2>&1; then
        if [ -f coverage.out ]; then
            coverage=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
            echo "$coverage"
        else
            echo "0"
        fi
    else
        print_error "Tests failed for branch: $branch"
        echo "0"
    fi
}

# Function to generate coverage report
generate_report() {
    local base_coverage=$1
    local current_coverage=$2
    local diff=$3
    
    print_info "Generating coverage report..."
    
    cat > coverage-gate-report.md << EOF
# Coverage Gate Report

## Summary
- **Base Branch ($BASE_BRANCH)**: ${base_coverage}%
- **Current Branch ($CURRENT_BRANCH)**: ${current_coverage}%
- **Difference**: ${diff}%
- **Threshold**: ${COVERAGE_THRESHOLD}%

## Status
EOF

    if (( $(echo "$diff < -$COVERAGE_THRESHOLD" | bc -l) )); then
        cat >> coverage-gate-report.md << EOF
❌ **COVERAGE GATE FAILED**

Coverage decreased by ${diff#-}%, which exceeds the allowed threshold of ${COVERAGE_THRESHOLD}%.

### Recommendations:
1. Add unit tests for new/modified code
2. Remove dead code if applicable
3. Ensure all code paths are tested
4. Consider refactoring complex functions to improve testability

EOF
    else
        cat >> coverage-gate-report.md << EOF
✅ **COVERAGE GATE PASSED**

Coverage change is within acceptable limits.

EOF
    fi

    # Add detailed package coverage
    echo "## Package Coverage Details" >> coverage-gate-report.md
    echo "" >> coverage-gate-report.md
    echo "| Package | Coverage |" >> coverage-gate-report.md
    echo "|---------|----------|" >> coverage-gate-report.md
    
    if [ -f coverage.out ]; then
        go tool cover -func=coverage.out | grep -v "total:" | while read line; do
            if [[ $line == *"/"* ]]; then
                pkg=$(echo "$line" | awk '{print $1}' | sed 's|^.*/||')
                cov=$(echo "$line" | awk '{print $3}')
                echo "| $pkg | $cov |" >> coverage-gate-report.md
            fi
        done
    fi
    
    echo "" >> coverage-gate-report.md
    echo "---" >> coverage-gate-report.md
    echo "*Report generated by coverage-gate.sh*" >> coverage-gate-report.md
    
    print_success "Coverage report saved to: coverage-gate-report.md"
}

# Function to show help
show_help() {
    cat << EOF
Coverage Gate Local Testing Script

Usage: $0 [OPTIONS]

Options:
  -b, --base BRANCH       Base branch to compare against (default: $BASE_BRANCH)
  -t, --threshold VALUE   Coverage decrease threshold (default: $COVERAGE_THRESHOLD)
  -r, --report           Generate detailed coverage report
  -h, --help             Show this help message

Examples:
  $0                      # Test current branch against main
  $0 -b develop          # Test against develop branch
  $0 -t 1.0              # Allow up to 1% decrease
  $0 -r                  # Generate detailed report

EOF
}

# Parse command line arguments
GENERATE_REPORT=false

while [[ $# -gt 0 ]]; do
    case $1 in
        -b|--base)
            BASE_BRANCH="$2"
            shift 2
            ;;
        -t|--threshold)
            COVERAGE_THRESHOLD="$2"
            shift 2
            ;;
        -r|--report)
            GENERATE_REPORT=true
            shift
            ;;
        -h|--help)
            show_help
            exit 0
            ;;
        *)
            print_error "Unknown option: $1"
            show_help
            exit 1
            ;;
    esac
done

# Main execution
print_info "Coverage Gate Local Test"
print_info "Base branch: $BASE_BRANCH"
print_info "Current branch: $CURRENT_BRANCH"
print_info "Threshold: $COVERAGE_THRESHOLD%"
echo ""

# Check if we're in a git repository
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    print_error "Not in a git repository"
    exit 1
fi

# Check if base branch exists
if ! git show-ref --verify --quiet "refs/heads/$BASE_BRANCH"; then
    print_error "Base branch '$BASE_BRANCH' does not exist"
    exit 1
fi

# Save current branch
ORIGINAL_BRANCH=$CURRENT_BRANCH

# Ensure we have a clean working directory
if ! git diff-index --quiet HEAD --; then
    print_warning "Working directory is not clean. Stashing changes..."
    git stash push -m "coverage-gate-temp-stash"
    STASHED=true
fi

# Get base branch coverage
print_info "Testing base branch coverage..."
BASE_COVERAGE=$(get_coverage "$BASE_BRANCH")

# Get current branch coverage
print_info "Testing current branch coverage..."
CURRENT_COVERAGE=$(get_coverage "$CURRENT_BRANCH")

# Calculate difference
DIFF=$(echo "$CURRENT_COVERAGE - $BASE_COVERAGE" | bc -l)

# Switch back to original branch
git checkout "$ORIGINAL_BRANCH" >/dev/null 2>&1

# Restore stashed changes if any
if [ "$STASHED" = true ]; then
    print_info "Restoring stashed changes..."
    git stash pop >/dev/null 2>&1
fi

# Display results
echo ""
echo "==============================================="
echo "              COVERAGE RESULTS"
echo "==============================================="
printf "Base Branch (%s):     %s%%\n" "$BASE_BRANCH" "$BASE_COVERAGE"
printf "Current Branch (%s): %s%%\n" "$CURRENT_BRANCH" "$CURRENT_COVERAGE"
printf "Difference:            %s%%\n" "$DIFF"
printf "Threshold:             %s%%\n" "$COVERAGE_THRESHOLD"
echo "==============================================="

# Generate report if requested
if [ "$GENERATE_REPORT" = true ]; then
    generate_report "$BASE_COVERAGE" "$CURRENT_COVERAGE" "$DIFF"
fi

# Check if coverage gate passes
if (( $(echo "$DIFF < -$COVERAGE_THRESHOLD" | bc -l) )); then
    print_error "Coverage Gate FAILED!"
    print_error "Coverage decreased by ${DIFF#-}%, exceeding threshold of ${COVERAGE_THRESHOLD}%"
    exit 1
else
    print_success "Coverage Gate PASSED!"
    if (( $(echo "$DIFF > 0" | bc -l) )); then
        print_success "Coverage improved by ${DIFF}%"
    elif (( $(echo "$DIFF == 0" | bc -l) )); then
        print_success "Coverage maintained"
    else
        print_success "Coverage decrease (${DIFF#-}%) is within acceptable limits"
    fi
fi