#!/bin/bash
#
# Pre-commit hook for rs-pfcp project
# Runs cargo fmt, clippy, and basic checks before allowing commits
#

set -e

echo "🔍 Running pre-commit checks..."

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

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

print_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

print_error() {
    echo -e "${RED}❌ $1${NC}"
}

# Check if we're in a Rust project
if [ ! -f "Cargo.toml" ]; then
    print_error "No Cargo.toml found in project root"
    exit 1
fi

# 1. Format check and auto-fix
print_status "Running cargo fmt..."
if ! cargo fmt --all -- --check >/dev/null 2>&1; then
    print_warning "Code formatting issues found. Auto-fixing..."
    cargo fmt --all

    # Check if there are any staged changes that got formatted
    if ! git diff --cached --quiet; then
        print_warning "Formatted files have been staged automatically"
        git add -u
    fi
fi
print_success "Code formatting passed"

# 2. Clippy linting
print_status "Running cargo clippy..."
if ! cargo clippy --all-targets --all-features -- -D warnings; then
    print_error "Clippy found linting issues that must be fixed before commit"
    echo "Please fix the issues above and try again."
    exit 1
fi
print_success "Clippy linting passed"

# 3. Check for common issues
print_status "Running additional checks..."

# Check for TODO/FIXME comments in staged files
staged_files=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(rs|toml)$' || true)
if [ -n "$staged_files" ]; then
    todo_count=$(git diff --cached | grep -E '^\+.*\b(TODO|FIXME)\b' | wc -l || true)
    if [ "$todo_count" -gt 0 ]; then
        print_warning "Found $todo_count new TODO/FIXME comments in staged changes"
        git diff --cached | grep -E '^\+.*\b(TODO|FIXME)\b' || true
        echo "Consider addressing these before committing."
    fi
fi

# Check for potential secrets (basic patterns)
if [ -n "$staged_files" ]; then
    secrets_found=$(git diff --cached | grep -iE '^\+.*(password|secret|key|token)\s*=\s*["\047][^"\047\s]+["\047]' | wc -l || true)
    if [ "$secrets_found" -gt 0 ]; then
        print_error "Potential secrets detected in staged changes:"
        git diff --cached | grep -iE '^\+.*(password|secret|key|token)\s*=\s*["\047][^"\047\s]+["\047]' || true
        echo "Please review and remove any actual secrets before committing."
        exit 1
    fi
fi

# 4. Build check for main project
print_status "Running cargo check..."
if ! cargo check --all-targets; then
    print_error "Project failed to compile"
    exit 1
fi
print_success "Cargo check passed"

# 5. Test check (if tests exist and are quick)
if cargo test --help >/dev/null 2>&1; then
    print_status "Running quick tests..."
    # Run tests with timeout to avoid long-running tests in pre-commit
    if timeout 30s cargo test --lib --bins 2>/dev/null; then
        print_success "Quick tests passed"
    else
        print_warning "Tests took too long or failed - skipping (run 'cargo test' manually)"
    fi
fi

# 6. Check benchmark project if we're in benchmarks directory
if [ -d "benchmarks/rust" ]; then
    print_status "Checking benchmark project..."
    (cd benchmarks/rust && cargo check) || {
        print_error "Benchmark project failed to compile"
        exit 1
    }
    print_success "Benchmark project check passed"
fi

# 7. Check for large files
large_files=$(git diff --cached --name-only | xargs -I {} sh -c 'if [ -f "{}" ] && [ $(stat -f%z "{}" 2>/dev/null || stat -c%s "{}" 2>/dev/null || echo 0) -gt 1048576 ]; then echo "{}"; fi' || true)
if [ -n "$large_files" ]; then
    print_warning "Large files detected (>1MB):"
    echo "$large_files"
    echo "Consider using Git LFS for large files."
fi

print_success "All pre-commit checks passed! 🚀"
echo ""
