#!/bin/bash

# Constant-Time Verification Script for clock-bigint
# This script runs various tests to verify constant-time properties

set -e

echo "🕐 Verifying constant-time properties of clock-bigint..."

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

# Function to print status
print_status() {
    echo -e "${GREEN}✓${NC} $1"
}

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

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

# Check if we have required tools
check_dependencies() {
    echo "Checking dependencies..."

    if ! command -v cargo &> /dev/null; then
        print_error "cargo not found"
        exit 1
    fi

    if ! command -v rustc &> /dev/null; then
        print_error "rustc not found"
        exit 1
    fi

    print_status "Dependencies OK"
}

# Run basic tests
run_basic_tests() {
    echo "Running basic test suite..."

    if cargo test --lib --release; then
        print_status "Basic tests passed"
    else
        print_error "Basic tests failed"
        exit 1
    fi
}

# Run constant-time specific tests
run_constant_time_tests() {
    echo "Running constant-time specific tests..."

    if cargo test --test constant_time --release; then
        print_status "Constant-time tests passed"
    else
        print_error "Constant-time tests failed"
        exit 1
    fi
}

# Run fuzz tests for constant-time verification
run_fuzz_constant_time() {
    echo "Running fuzz tests for constant-time verification..."

    if command -v cargo-fuzz &> /dev/null; then
        # Run fuzzing for a short time to catch obvious issues
        timeout 60 cargo fuzz run constant_time -- -runs=10000 || {
            print_warning "Fuzz testing timed out or found issues"
            return 1
        }
        print_status "Constant-time fuzz tests passed"
    else
        print_warning "cargo-fuzz not available, skipping fuzz tests"
    fi
}

# Check for timing-dependent code patterns
check_code_patterns() {
    echo "Checking for timing-dependent code patterns..."

    local issues_found=0

    # Check for if statements that might depend on secret data
    if grep -r "if.*secret\|if.*key\|if.*private" src/ --include="*.rs" | grep -v "test"; then
        print_warning "Found conditional statements that may depend on secret data"
        issues_found=$((issues_found + 1))
    fi

    # Check for variable-time operations
    if grep -r "vec!\|\.len()\|resize\|push\|pop" src/ --include="*.rs" | grep -v "test\|const"; then
        print_warning "Found variable-length operations that may leak timing"
        issues_found=$((issues_found + 1))
    fi

    # Check for unsafe code in crypto paths
    if grep -r "unsafe" src/montgomery.rs src/modexp.rs src/mul.rs 2>/dev/null; then
        print_warning "Found unsafe code in cryptographic functions"
        issues_found=$((issues_found + 1))
    fi

    if [ $issues_found -eq 0 ]; then
        print_status "Code pattern check passed"
    else
        print_warning "Found $issues_found potential timing issues"
    fi
}

# Run performance benchmarks and check for anomalies
check_performance_anomalies() {
    echo "Checking for performance anomalies..."

    if command -v hyperfine &> /dev/null; then
        # Quick benchmark comparison
        echo "Running quick performance check..."

        # This is a simplified check - in practice you'd want more sophisticated analysis
        if cargo build --release --quiet; then
            print_status "Performance check completed"
        fi
    else
        print_warning "hyperfine not available for detailed performance analysis"
    fi
}

# Check for branch-free implementations
check_branch_free() {
    echo "Checking for branch-free implementations..."

    # Look for select/cmov patterns that indicate constant-time code
    if grep -r "select\|cmov\|choose" src/ --include="*.rs"; then
        print_status "Found branch-free operation patterns"
    else
        print_warning "No explicit branch-free patterns found"
    fi
}

# Main verification function
main() {
    echo "========================================"
    echo "clock-bigint Constant-Time Verification"
    echo "========================================"
    echo

    check_dependencies
    echo

    run_basic_tests
    echo

    run_constant_time_tests
    echo

    run_fuzz_constant_time
    echo

    check_code_patterns
    echo

    check_performance_anomalies
    echo

    check_branch_free
    echo

    echo "========================================"
    print_status "Constant-time verification completed"
    echo "Review any warnings above and address them"
    echo "========================================"
}

# Run main function
main "$@"