#!/bin/bash

# Comprehensive Security Testing Script for clock-bigint
# Runs all security-related tests and checks

set -e

echo "🔒 Running comprehensive security tests for clock-bigint..."

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

# 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"
}

print_info() {
    echo -e "${BLUE}ℹ${NC} $1"
}

# Test results tracking
TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0

record_test() {
    local name=$1
    local result=$2

    TESTS_RUN=$((TESTS_RUN + 1))

    if [ "$result" -eq 0 ]; then
        TESTS_PASSED=$((TESTS_PASSED + 1))
        print_status "$name"
    else
        TESTS_FAILED=$((TESTS_FAILED + 1))
        print_error "$name"
    fi
}

# Run unit tests
test_unit_tests() {
    print_info "Running unit tests..."
    if cargo test --lib --release; then
        record_test "Unit tests" 0
    else
        record_test "Unit tests" 1
    fi
}

# Run integration tests
test_integration() {
    print_info "Running integration tests..."
    if cargo test --test integration --release; then
        record_test "Integration tests" 0
    else
        record_test "Integration tests" 1
    fi
}

# Run compliance/property tests
test_compliance() {
    print_info "Running compliance tests..."
    if cargo test --test compliance --release; then
        record_test "Compliance tests" 0
    else
        record_test "Compliance tests" 1
    fi
}

# Run constant-time tests
test_constant_time() {
    print_info "Running constant-time tests..."
    if cargo test --test constant_time --release; then
        record_test "Constant-time tests" 0
    else
        record_test "Constant-time tests" 1
    fi
}

# Test no-std compatibility
test_no_std() {
    print_info "Testing no-std compatibility..."
    if cargo build --no-default-features --release; then
        record_test "No-std build" 0
    else
        record_test "No-std build" 1
    fi
}

# Test fuzz targets (short run)
test_fuzz_short() {
    print_info "Running short fuzz tests..."
    local success=0

    if command -v cargo-fuzz &> /dev/null; then
        # Test each fuzz target for 30 seconds
        for target in constant_time edge_cases crypto_ops; do
            print_info "  Testing $target fuzz target..."
            if timeout 30 cargo fuzz run $target -- -runs=5000 2>/dev/null; then
                print_status "  $target fuzz test passed"
            else
                print_warning "  $target fuzz test found issues or timed out"
                success=1
            fi
        done
    else
        print_warning "cargo-fuzz not available"
        success=1
    fi

    record_test "Fuzz tests" $success
}

# Check for security vulnerabilities
test_vulnerabilities() {
    print_info "Checking for security vulnerabilities..."
    local success=0

    if command -v cargo-audit &> /dev/null; then
        if cargo audit --quiet; then
            record_test "Security audit" 0
        else
            print_warning "Security vulnerabilities found"
            record_test "Security audit" 1
        fi
    else
        print_warning "cargo-audit not available"
        record_test "Security audit" 1
    fi
}

# Run clippy lints
test_lints() {
    print_info "Running clippy lints..."
    if cargo clippy --all-targets --all-features -- -D warnings; then
        record_test "Clippy lints" 0
    else
        record_test "Clippy lints" 1
    fi
}

# Check memory safety
test_memory_safety() {
    print_info "Testing memory safety..."
    if cargo test --release -- --test-threads=1; then
        record_test "Memory safety" 0
    else
        record_test "Memory safety" 1
    fi
}

# Check documentation coverage
test_docs() {
    print_info "Checking documentation..."
    if cargo doc --no-deps --document-private-items 2>&1 | grep -q "warning.*missing"; then
        print_warning "Missing documentation found"
        record_test "Documentation" 1
    else
        record_test "Documentation" 0
    fi
}

# Run benchmarks
test_benchmarks() {
    print_info "Running benchmarks..."
    if cargo bench --quiet; then
        record_test "Benchmarks" 0
    else
        record_test "Benchmarks" 1
    fi
}

# Cross-platform build test
test_cross_platform() {
    print_info "Testing cross-platform compatibility..."
    local success=0

    # Test different target architectures if cross is available
    if command -v cross &> /dev/null; then
        for target in x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
            print_info "  Building for $target..."
            if cross build --target $target --release; then
                print_status "  $target build successful"
            else
                print_warning "  $target build failed"
                success=1
            fi
        done
    else
        print_warning "cross not available, skipping cross-platform tests"
        success=1
    fi

    record_test "Cross-platform" $success
}

# Generate security report
generate_report() {
    echo
    echo "========================================"
    echo "🔒 Security Test Report"
    echo "========================================"
    echo "Tests run: $TESTS_RUN"
    echo "Tests passed: $TESTS_PASSED"
    echo "Tests failed: $TESTS_FAILED"
    echo

    if [ $TESTS_FAILED -eq 0 ]; then
        print_status "All security tests passed!"
        echo "✅ Code is ready for security review"
    else
        print_error "$TESTS_FAILED security tests failed"
        echo "⚠️  Address the failed tests before proceeding"
        exit 1
    fi

    echo "========================================"
}

# Main function
main() {
    echo "========================================"
    echo "🔒 clock-bigint Security Test Suite"
    echo "========================================"
    echo

    # Run all tests
    test_unit_tests
    test_integration
    test_compliance
    test_constant_time
    test_no_std
    test_fuzz_short
    test_vulnerabilities
    test_lints
    test_memory_safety
    test_docs
    test_benchmarks
    test_cross_platform

    # Generate final report
    generate_report
}

# Run main function
main "$@"