<?php
/**
 * Security Testing Script
 * Tests all implemented security measures to ensure they work correctly
 */

// Security: This script should only be run from command line
if (php_sapi_name() !== 'cli') {
    die("This script can only be run from command line.\n");
}

require_once '../middleware/InputValidator.php';
require_once '../middleware/SecurityLogger.php';
require_once '../middleware/Auth.php';
require_once '../config/Database.php';

echo "=== Security Testing Suite ===\n\n";

$testsPassed = 0;
$testsTotal = 0;

/**
 * Test helper function
 */
function runTest($testName, $testFunction) {
    global $testsPassed, $testsTotal;
    $testsTotal++;

    echo "Testing: $testName... ";

    try {
        $result = $testFunction();
        if ($result) {
            echo "✓ PASSED\n";
            $testsPassed++;
        } else {
            echo "✗ FAILED\n";
        }
    } catch (Exception $e) {
        echo "✗ ERROR: " . $e->getMessage() . "\n";
    }
}

/**
 * Test input validation
 */
function testInputValidation() {
    // Test email validation
    $validEmail = InputValidator::validateEmail('test@example.com');
    $invalidEmail = InputValidator::validateEmail('invalid-email');

    if (!$validEmail || $invalidEmail) {
        return false;
    }

    // Test password validation
    $validPassword = InputValidator::validatePassword('SecurePass123!');
    $invalidPassword = InputValidator::validatePassword('weak');

    if (!$validPassword || $invalidPassword) {
        return false;
    }

    // Test SQL injection detection
    $cleanInput = 'normal input';
    $sqlInjection = "'; DROP TABLE users; --";

    $cleanResult = InputValidator::checkSQLInjection($cleanInput);
    $injectionResult = InputValidator::checkSQLInjection($sqlInjection);

    if ($cleanResult || !$injectionResult) {
        return false;
    }

    // Test XSS detection
    $cleanXSS = 'normal text';
    $xssAttack = '<script>alert("xss")</script>';

    $cleanXSSResult = InputValidator::checkXSS($cleanXSS);
    $xssResult = InputValidator::checkXSS($xssAttack);

    if ($cleanXSSResult || !$xssResult) {
        return false;
    }

    return true;
}

/**
 * Test rate limiting
 */
function testRateLimiting() {
    $testIP = '192.168.1.100';

    // Reset any existing counts for this IP
    InputValidator::resetRateLimit($testIP);

    // Should allow initial requests
    $firstRequest = InputValidator::checkRateLimit($testIP, 5, 60);
    $secondRequest = InputValidator::checkRateLimit($testIP, 5, 60);

    if (!$firstRequest || !$secondRequest) {
        return false;
    }

    // Fill up the rate limit
    for ($i = 0; $i < 3; $i++) {
        InputValidator::checkRateLimit($testIP, 5, 60);
    }

    // This should be blocked (6th request, limit is 5)
    $blockedRequest = InputValidator::checkRateLimit($testIP, 5, 60);

    return $blockedRequest === false;
}

/**
 * Test JWT token security
 */
function testJWT() {
    // Test token generation
    $testUser = ['id' => 1, 'username' => 'testuser', 'role' => 'Agent'];

    $token = Auth::generateToken($testUser);
    if (!$token) {
        return false;
    }

    // Test token verification
    $decoded = Auth::verifyToken($token);
    if (!$decoded) {
        return false;
    }

    // Test token tampering
    $tamperedToken = $token . 'tampered';
    $tamperedResult = Auth::verifyToken($tamperedToken);

    if ($tamperedResult !== false) {
        return false;
    }

    // Test expired token simulation (hard to test naturally)
    // This would require modifying the token payload manually

    return true;
}

/**
 * Test database security
 */
function testDatabaseSecurity() {
    try {
        $db = new Database();
        $conn = $db->getConnection();

        // Test prepared statement
        $stmt = $conn->prepare("SELECT 1 as test WHERE ? = ?");
        $stmt->execute(['test', 'test']);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($result['test'] !== 1) {
            return false;
        }

        // Test against SQL injection in prepared statement
        $maliciousInput = "'; DROP TABLE users; --";
        $stmt = $conn->prepare("SELECT :input as safe_input");
        $stmt->bindParam(':input', $maliciousInput);
        $stmt->execute();
        $result = $stmt->fetch(PDO::FETCH_ASSOC);

        // Should return the malicious input as-is (escaped)
        if ($result['safe_input'] !== $maliciousInput) {
            return false;
        }

        $db->closeConnection();
        return true;

    } catch (Exception $e) {
        return false;
    }
}

/**
 * Test security logging
 */
function testSecurityLogging() {
    $testEvent = 'TEST_SECURITY_EVENT';
    $testDetails = ['test' => 'data', 'timestamp' => time()];

    // Log a test event
    SecurityLogger::logSecurityEvent($testEvent, 'INFO', $testDetails);

    // Check if log file exists
    $logFile = '../logs/security.log';
    if (!file_exists($logFile)) {
        return false;
    }

    // Check recent events
    $recentEvents = SecurityLogger::getRecentEvents(10);
    if (empty($recentEvents)) {
        return false;
    }

    // Find our test event
    $foundTestEvent = false;
    foreach ($recentEvents as $event) {
        if (isset($event['event']) && $event['event'] === $testEvent) {
            $foundTestEvent = true;
            break;
        }
    }

    return $foundTestEvent;
}

/**
 * Test CORS security
 */
function testCORSSecurity() {
    // Test allowed origins
    $allowedOrigins = [
        'https://transub.dz',
        'https://www.transub.dz',
        'https://api.transub.dz'
    ];

    $testOrigin = 'https://transub.dz';
    $isAllowed = in_array($testOrigin, $allowedOrigins);

    if (!$isAllowed) {
        return false;
    }

    // Test disallowed origin
    $disallowedOrigin = 'https://malicious-site.com';
    $isDisallowed = !in_array($disallowedOrigin, $allowedOrigins);

    return $isDisallowed;
}

/**
 * Test file permissions (basic check)
 */
function testFilePermissions() {
    $configFiles = [
        '../config/database_secure.php',
        '../config/jwt_secure.php'
    ];

    foreach ($configFiles as $file) {
        if (file_exists($file)) {
            $perms = fileperms($file);
            // Check if file is readable (should be, but not world-readable)
            if (!is_readable($file)) {
                return false;
            }
        }
    }

    return true;
}

// Run all tests
echo "Running security tests...\n\n";

runTest('Input Validation', 'testInputValidation');
runTest('Rate Limiting', 'testRateLimiting');
runTest('JWT Token Security', 'testJWT');
runTest('Database Security', 'testDatabaseSecurity');
runTest('Security Logging', 'testSecurityLogging');
runTest('CORS Security', 'testCORSSecurity');
runTest('File Permissions', 'testFilePermissions');

echo "\n=== Test Results ===\n";
echo "Passed: $testsPassed/$testsTotal tests\n";

if ($testsPassed === $testsTotal) {
    echo "🎉 All security tests PASSED!\n";
    echo "Your application security is properly configured.\n\n";

    echo "=== Security Recommendations ===\n";
    echo "✓ Keep all dependencies updated\n";
    echo "✓ Rotate encryption keys regularly (90 days)\n";
    echo "✓ Monitor security logs for suspicious activity\n";
    echo "✓ Run regular security scans\n";
    echo "✓ Keep backups secure and encrypted\n";
    echo "✓ Use HTTPS in production\n";
    echo "✓ Implement proper firewall rules\n\n";

    exit(0);
} else {
    echo "❌ Some security tests FAILED!\n";
    echo "Please review and fix the failed tests before deploying to production.\n\n";

    echo "=== Next Steps ===\n";
    echo "1. Check error messages above\n";
    echo "2. Review security configurations\n";
    echo "3. Test manually if needed\n";
    echo "4. Re-run this test after fixes\n\n";

    exit(1);
}
?>
