#!/usr/bin/env bash

# ============================================================================
# Nginx Configuration Test Suite
# Validates all template configurations for syntax and security standards
# ============================================================================

set -euo pipefail

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

# Counters
TOTAL_TESTS=0
PASSED_TESTS=0
FAILED_TESTS=0

# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMPLATES_DIR="$(dirname "$SCRIPT_DIR")/templates"
VALIDATOR_SCRIPT="$(dirname "$SCRIPT_DIR")/scripts/validate-nginx-config.sh"

# ============================================================================
# Helper Functions
# ============================================================================

print_header() {
    echo ""
    echo -e "${BLUE}============================================================================${NC}"
    echo -e "${BLUE}$1${NC}"
    echo -e "${BLUE}============================================================================${NC}"
    echo ""
}

print_success() {
    echo -e "${GREEN}✓ $1${NC}"
    ((PASSED_TESTS++))
}

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

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

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

# ============================================================================
# Test Functions
# ============================================================================

test_template_exists() {
    local template_name="$1"
    local template_file="$2"

    ((TOTAL_TESTS++))

    if [[ -f "$template_file" ]]; then
        print_success "Template exists: $template_name"
        return 0
    else
        print_error "Template missing: $template_name ($template_file)"
        return 1
    fi
}

test_template_syntax() {
    local template_name="$1"
    local template_file="$2"

    ((TOTAL_TESTS++))

    # Check if template contains basic Nginx structure
    if grep -q "server {" "$template_file" && \
       grep -q "listen" "$template_file" && \
       grep -q "server_name" "$template_file"; then
        print_success "Valid Nginx structure: $template_name"
        return 0
    else
        print_error "Invalid Nginx structure: $template_name"
        return 1
    fi
}

test_ssl_configuration() {
    local template_name="$1"
    local template_file="$2"

    ((TOTAL_TESTS++))

    # Check for modern TLS protocols
    if grep -q "ssl_protocols.*TLSv1.2.*TLSv1.3\|ssl_protocols.*TLSv1.3.*TLSv1.2" "$template_file"; then
        print_success "Modern TLS protocols: $template_name"
    else
        print_error "Missing or outdated TLS protocols: $template_name"
        return 1
    fi

    ((TOTAL_TESTS++))

    # Check for OCSP stapling
    if grep -q "ssl_stapling on" "$template_file"; then
        print_success "OCSP stapling enabled: $template_name"
    else
        print_warning "OCSP stapling missing: $template_name"
    fi

    return 0
}

test_security_headers() {
    local template_name="$1"
    local template_file="$2"

    local required_headers=(
        "Strict-Transport-Security"
        "X-Frame-Options"
        "X-Content-Type-Options"
        "Content-Security-Policy"
    )

    for header in "${required_headers[@]}"; do
        ((TOTAL_TESTS++))

        if grep -q "$header" "$template_file"; then
            print_success "Security header present ($header): $template_name"
        else
            print_error "Missing security header ($header): $template_name"
            ((FAILED_TESTS++))
        fi
    done
}

test_rate_limiting() {
    local template_name="$1"
    local template_file="$2"

    ((TOTAL_TESTS++))

    if grep -q "limit_req_zone" "$template_file"; then
        print_success "Rate limiting configured: $template_name"
        return 0
    else
        print_warning "No rate limiting: $template_name"
        return 1
    fi
}

test_server_tokens() {
    local template_name="$1"
    local template_file="$2"

    ((TOTAL_TESTS++))

    if grep -q "server_tokens off" "$template_file"; then
        print_success "Server tokens disabled: $template_name"
        return 0
    else
        print_error "Server tokens not disabled: $template_name"
        return 1
    fi
}

test_https_redirect() {
    local template_name="$1"
    local template_file="$2"

    ((TOTAL_TESTS++))

    if grep -q "return 301 https://" "$template_file"; then
        print_success "HTTPS redirect configured: $template_name"
        return 0
    else
        print_warning "No HTTPS redirect: $template_name"
        return 1
    fi
}

test_compression() {
    local template_name="$1"
    local template_file="$2"

    ((TOTAL_TESTS++))

    if grep -q "gzip on" "$template_file"; then
        print_success "Gzip compression enabled: $template_name"
        return 0
    else
        print_warning "Gzip compression not enabled: $template_name"
        return 1
    fi
}

test_logging() {
    local template_name="$1"
    local template_file="$2"

    ((TOTAL_TESTS++))

    if grep -q "access_log" "$template_file" && grep -q "error_log" "$template_file"; then
        print_success "Logging configured: $template_name"
        return 0
    else
        print_error "Logging not configured: $template_name"
        return 1
    fi
}

test_documentation() {
    local template_name="$1"
    local template_file="$2"

    ((TOTAL_TESTS++))

    # Check if template has comments
    local comment_count=$(grep -c "^[[:space:]]*#" "$template_file" || true)

    if [[ $comment_count -gt 20 ]]; then
        print_success "Well documented ($comment_count comments): $template_name"
        return 0
    else
        print_warning "Could use more documentation ($comment_count comments): $template_name"
        return 1
    fi
}

# ============================================================================
# Run Tests for Single Template
# ============================================================================

test_template() {
    local template_name="$1"
    local template_file="$2"

    print_header "Testing: $template_name"

    # Basic tests
    test_template_exists "$template_name" "$template_file" || return 1
    test_template_syntax "$template_name" "$template_file" || return 1

    # Security tests
    test_ssl_configuration "$template_name" "$template_file"
    test_security_headers "$template_name" "$template_file"
    test_server_tokens "$template_name" "$template_file"

    # Feature tests
    test_rate_limiting "$template_name" "$template_file"
    test_https_redirect "$template_name" "$template_file"
    test_compression "$template_name" "$template_file"
    test_logging "$template_name" "$template_file"

    # Documentation test
    test_documentation "$template_name" "$template_file"

    echo ""
}

# ============================================================================
# Main Script
# ============================================================================

print_header "Nginx Configuration Test Suite"

print_info "Templates directory: $TEMPLATES_DIR"
echo ""

# Check if templates directory exists
if [[ ! -d "$TEMPLATES_DIR" ]]; then
    print_error "Templates directory not found: $TEMPLATES_DIR"
    exit 1
fi

# Test each template
test_template "Reverse Proxy" "$TEMPLATES_DIR/reverse-proxy/reverse-proxy.conf"
test_template "Load Balancer" "$TEMPLATES_DIR/load-balancer/load-balancer.conf"
test_template "Static Site" "$TEMPLATES_DIR/static-site/static-site.conf"
test_template "SSL Termination" "$TEMPLATES_DIR/ssl-termination/ssl-termination.conf"
test_template "API Gateway" "$TEMPLATES_DIR/api-gateway/api-gateway.conf"

# ============================================================================
# Advanced Tests (if nginx is available)
# ============================================================================

if command -v nginx &> /dev/null; then
    print_header "Nginx Syntax Validation"
    print_warning "Nginx not installed - skipping syntax validation"
    print_info "Install nginx to enable syntax checks: sudo apt install nginx"
    echo ""
else
    print_warning "Nginx not installed - skipping syntax validation"
    print_info "Install nginx to enable syntax checks: sudo apt install nginx"
    echo ""
fi

# ============================================================================
# Security Standards Check
# ============================================================================

print_header "Security Standards Check"

for template_name in "${!templates[@]}"; do
    template_file="${templates[$template_name]}"

    ((TOTAL_TESTS++))

    # Check for no outdated protocols
    if grep -q "SSLv\|TLSv1\.0\|TLSv1\.1" "$template_file"; then
        print_error "Outdated SSL/TLS protocols found: $template_name"
        ((FAILED_TESTS++))
    else
        print_success "No outdated protocols: $template_name"
        ((PASSED_TESTS++))
    fi

    ((TOTAL_TESTS++))

    # Check for no weak ciphers
    if grep -q "RC4\|MD5\|DES\|3DES" "$template_file"; then
        print_error "Weak ciphers found: $template_name"
        ((FAILED_TESTS++))
    else
        print_success "No weak ciphers: $template_name"
        ((PASSED_TESTS++))
    fi
done

echo ""

# ============================================================================
# Test Summary
# ============================================================================

print_header "Test Summary"

echo "Total Tests:   $TOTAL_TESTS"
echo -e "${GREEN}Passed:        $PASSED_TESTS${NC}"
echo -e "${RED}Failed:        $FAILED_TESTS${NC}"
echo ""

# Calculate percentage
if [[ $TOTAL_TESTS -gt 0 ]]; then
    pass_percentage=$((PASSED_TESTS * 100 / TOTAL_TESTS))
    echo "Success Rate:  $pass_percentage%"
    echo ""
fi

# Exit status
if [[ $FAILED_TESTS -eq 0 ]]; then
    print_success "All tests passed!"
    echo ""
    echo "✓ All templates are production-ready"
    echo "✓ Security standards met"
    echo "✓ Best practices followed"
    echo ""
    exit 0
else
    print_error "$FAILED_TESTS test(s) failed"
    echo ""
    echo "Please review the failed tests above and fix the issues."
    echo ""
    exit 1
fi
