<?php
/**
 * Security Utilities Class
 * Provides security helper functions for the application
 */

class SecurityUtils {
    
    /**
     * Generate CSRF token
     */
    public static function generateCSRFToken() {
        if (!isset($_SESSION['csrf_token'])) {
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        }
        return $_SESSION['csrf_token'];
    }
    
    /**
     * Verify CSRF token
     */
    public static function verifyCSRFToken($token) {
        return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
    }
    
    /**
     * Get CSRF token for forms
     */
    public static function getCSRFField() {
        return '<input type="hidden" name="csrf_token" value="' . htmlspecialchars(self::generateCSRFToken()) . '">';
    }
    
    /**
     * Validate email format
     */
    public static function validateEmail($email) {
        $email = trim($email);
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return false;
        }
        return $email;
    }
    
    /**
     * Validate password strength
     */
    public static function validatePassword($password) {
        if (strlen($password) < 8) {
            return array('valid' => false, 'message' => 'Password must be at least 8 characters');
        }
        if (!preg_match('/[A-Z]/', $password)) {
            return array('valid' => false, 'message' => 'Password must contain at least one uppercase letter');
        }
        if (!preg_match('/[a-z]/', $password)) {
            return array('valid' => false, 'message' => 'Password must contain at least one lowercase letter');
        }
        if (!preg_match('/[0-9]/', $password)) {
            return array('valid' => false, 'message' => 'Password must contain at least one number');
        }
        if (!preg_match('/[!@#$%^&*]/', $password)) {
            return array('valid' => false, 'message' => 'Password must contain at least one special character (!@#$%^&*)');
        }
        return array('valid' => true, 'message' => 'Password is strong');
    }
    
    /**
     * Validate phone number (US format)
     */
    public static function validatePhone($phone) {
        $phone = preg_replace('/[^0-9]/', '', $phone);
        if (strlen($phone) != 10) {
            return false;
        }
        return $phone;
    }
    
    /**
     * Validate numeric input
     */
    public static function validateNumeric($value, $min = null, $max = null) {
        if (!is_numeric($value)) {
            return false;
        }
        if ($min !== null && $value < $min) {
            return false;
        }
        if ($max !== null && $value > $max) {
            return false;
        }
        return (float)$value;
    }
    
    /**
     * Validate account number format
     */
    public static function validateAccountNumber($acctNo) {
        // Account numbers should be numeric and between 9-17 digits
        $acctNo = preg_replace('/[^0-9]/', '', $acctNo);
        if (strlen($acctNo) < 9 || strlen($acctNo) > 17) {
            return false;
        }
        return $acctNo;
    }
    
    /**
     * Sanitize string input for safe output
     */
    public static function sanitizeOutput($string) {
        return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
    }
    
    /**
     * Validate and sanitize input with type checking
     */
    public static function validateInput($value, $type = 'string', $maxLength = 255) {
        if (is_null($value)) {
            return '';
        }
        
        $value = trim($value);
        
        switch ($type) {
            case 'email':
                return self::validateEmail($value);
            case 'phone':
                return self::validatePhone($value);
            case 'numeric':
                return self::validateNumeric($value);
            case 'integer':
                return is_numeric($value) ? intval($value) : false;
            case 'string':
            default:
                if (strlen($value) > $maxLength) {
                    return substr($value, 0, $maxLength);
                }
                return trim(htmlspecialchars(htmlentities($value), ENT_QUOTES, 'UTF-8'));
        }
    }
    
    /**
     * Rate limiting - check if action is rate limited
     */
    public static function isRateLimited($action, $limit = 5, $timeWindow = 300) {
        $key = "ratelimit_" . $action . "_" . $_SERVER['REMOTE_ADDR'];
        
        if (!isset($_SESSION[$key])) {
            $_SESSION[$key] = array('count' => 0, 'first_attempt' => time());
        }
        
        $elapsed = time() - $_SESSION[$key]['first_attempt'];
        
        // Reset if time window has passed
        if ($elapsed > $timeWindow) {
            $_SESSION[$key] = array('count' => 1, 'first_attempt' => time());
            return false;
        }
        
        // Increment counter
        $_SESSION[$key]['count']++;
        
        return $_SESSION[$key]['count'] > $limit;
    }
    
    /**
     * Log security event
     */
    public static function logSecurityEvent($eventType, $details = array()) {
        $logDir = $_SERVER['DOCUMENT_ROOT'] . '/include/security_logs';
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755, true);
        }
        
        $logFile = $logDir . '/security_' . date('Y-m-d') . '.log';
        $timestamp = date('Y-m-d H:i:s');
        $ip = $_SERVER['REMOTE_ADDR'];
        $user = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : 'unknown';
        
        $logMessage = "[{$timestamp}] IP: {$ip} | User: {$user} | Event: {$eventType} | Details: " . json_encode($details) . PHP_EOL;
        
        error_log($logMessage, 3, $logFile);
    }
    
    /**
     * Secure password hash verification
     */
    public static function verifyPassword($password, $hash) {
        return password_verify($password, $hash);
    }
    
    /**
     * Generate secure password hash
     */
    public static function hashPassword($password) {
        return password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
    }
}
?>
