<?php
/**
 * Security Logger
 * Logs security events and suspicious activities
 */

class SecurityLogger {
    private static $logFile = __DIR__ . '/../logs/security.log';
    private static $maxFileSize = 10485760; // 10MB

    /**
     * Log security event
     */
    public static function logSecurityEvent($event, $severity = 'INFO', $details = []) {
        $logEntry = [
            'timestamp' => date('Y-m-d H:i:s'),
            'severity' => strtoupper($severity),
            'event' => $event,
            'ip' => self::getClientIP(),
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown',
            'details' => $details
        ];

        self::writeLog($logEntry);
    }

    /**
     * Log authentication attempts
     */
    public static function logAuthAttempt($username, $success = false, $details = []) {
        $event = $success ? 'AUTH_SUCCESS' : 'AUTH_FAILED';
        $severity = $success ? 'INFO' : 'WARNING';

        $details = array_merge($details, [
            'username' => $username,
            'success' => $success
        ]);

        self::logSecurityEvent($event, $severity, $details);
    }

    /**
     * Log SQL injection attempts
     */
    public static function logSQLInjectionAttempt($input, $location = 'unknown') {
        self::logSecurityEvent('SQL_INJECTION_ATTEMPT', 'CRITICAL', [
            'input' => substr($input, 0, 100), // Limit logged input length
            'location' => $location,
            'input_length' => strlen($input)
        ]);
    }

    /**
     * Log XSS attempts
     */
    public static function logXSSAttempt($input, $location = 'unknown') {
        self::logSecurityEvent('XSS_ATTEMPT', 'HIGH', [
            'input' => substr($input, 0, 100), // Limit logged input length
            'location' => $location,
            'input_length' => strlen($input)
        ]);
    }

    /**
     * Log rate limit exceeded
     */
    public static function logRateLimitExceeded($identifier, $limit, $window) {
        self::logSecurityEvent('RATE_LIMIT_EXCEEDED', 'WARNING', [
            'identifier' => $identifier,
            'limit' => $limit,
            'window_seconds' => $window
        ]);
    }

    /**
     * Log suspicious request patterns
     */
    public static function logSuspiciousRequest($reason, $details = []) {
        self::logSecurityEvent('SUSPICIOUS_REQUEST', 'WARNING', array_merge([
            'reason' => $reason
        ], $details));
    }

    /**
     * Get client IP address
     */
    private static function getClientIP() {
        $ipHeaders = [
            'HTTP_CF_CONNECTING_IP', // Cloudflare
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_FORWARDED',
            'HTTP_X_REAL_IP',
            'HTTP_CLIENT_IP',
            'REMOTE_ADDR'
        ];

        foreach ($ipHeaders as $header) {
            if (!empty($_SERVER[$header])) {
                $ip = $_SERVER[$header];

                // Handle multiple IPs (take the first one)
                if (strpos($ip, ',') !== false) {
                    $ip = trim(explode(',', $ip)[0]);
                }

                // Validate IP
                if (filter_var($ip, FILTER_VALIDATE_IP)) {
                    return $ip;
                }
            }
        }

        return 'unknown';
    }

    /**
     * Write log entry to file
     */
    private static function writeLog($logEntry) {
        // Ensure log directory exists
        $logDir = dirname(self::$logFile);
        if (!is_dir($logDir)) {
            mkdir($logDir, 0750, true);
        }

        // Rotate log file if too large
        if (file_exists(self::$logFile) && filesize(self::$logFile) > self::$maxFileSize) {
            $backupFile = self::$logFile . '.' . date('Y-m-d-H-i-s') . '.bak';
            rename(self::$logFile, $backupFile);
        }

        // Format log entry
        $formattedEntry = json_encode($logEntry, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;

        // Write to file
        file_put_contents(self::$logFile, $formattedEntry, FILE_APPEND | LOCK_EX);
    }

    /**
     * Get recent security events
     */
    public static function getRecentEvents($limit = 100, $severity = null) {
        if (!file_exists(self::$logFile)) {
            return [];
        }

        $lines = array_slice(file(self::$logFile), -$limit);
        $events = [];

        foreach ($lines as $line) {
            $entry = json_decode(trim($line), true);
            if ($entry) {
                if ($severity === null || strtoupper($entry['severity']) === strtoupper($severity)) {
                    $events[] = $entry;
                }
            }
        }

        return array_reverse($events); // Most recent first
    }

    /**
     * Clean old log files
     */
    public static function cleanupOldLogs($daysToKeep = 30) {
        $logDir = dirname(self::$logFile);
        if (!is_dir($logDir)) {
            return;
        }

        $files = glob($logDir . '/*.bak');
        $cutoffTime = time() - ($daysToKeep * 24 * 60 * 60);

        foreach ($files as $file) {
            if (filemtime($file) < $cutoffTime) {
                unlink($file);
            }
        }
    }
}
