<?php
// Security configuration and utilities

// Password policy
define('PASSWORD_MIN_LENGTH', 8);
define('PASSWORD_REQUIRE_UPPERCASE', true);
define('PASSWORD_REQUIRE_LOWERCASE', true);
define('PASSWORD_REQUIRE_NUMBERS', true);
define('PASSWORD_REQUIRE_SPECIAL_CHARS', false);

// Session security
define('SESSION_LIFETIME', 30 * 60); // 30 minutes
define('SESSION_REGENERATE_INTERVAL', 10 * 60); // Regenerate session ID every 10 minutes

// Rate limiting
define('MAX_LOGIN_ATTEMPTS', 5);
define('LOGIN_LOCKOUT_TIME', 15 * 60); // 15 minutes
define('MAX_REQUESTS_PER_HOUR', 1000);

// File upload security
define('MAX_FILE_SIZE', 5 * 1024 * 1024); // 5MB
define('ALLOWED_FILE_TYPES', ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx']);
define('UPLOAD_PATH', '../uploads/');

// CSRF protection functions are defined in auth.php

// Input sanitization
function sanitizeInput($input) {
    if (is_array($input)) {
        return array_map('sanitizeInput', $input);
    }
    return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}

// Password validation
function validatePassword($password) {
    if (strlen($password) < PASSWORD_MIN_LENGTH) {
        return false;
    }

    if (PASSWORD_REQUIRE_UPPERCASE && !preg_match('/[A-Z]/', $password)) {
        return false;
    }

    if (PASSWORD_REQUIRE_LOWERCASE && !preg_match('/[a-z]/', $password)) {
        return false;
    }

    if (PASSWORD_REQUIRE_NUMBERS && !preg_match('/[0-9]/', $password)) {
        return false;
    }

    if (PASSWORD_REQUIRE_SPECIAL_CHARS && !preg_match('/[^A-Za-z0-9]/', $password)) {
        return false;
    }

    return true;
}

// Secure file upload
function handleFileUpload($file, $destination = null) {
    if (!$destination) {
        $destination = UPLOAD_PATH;
    }

    // Check file size
    if ($file['size'] > MAX_FILE_SIZE) {
        return ['success' => false, 'message' => 'File too large'];
    }

    // Check file type
    $fileExtension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    if (!in_array($fileExtension, ALLOWED_FILE_TYPES)) {
        return ['success' => false, 'message' => 'File type not allowed'];
    }

    // Generate secure filename
    $secureFilename = bin2hex(random_bytes(16)) . '.' . $fileExtension;
    $fullPath = $destination . $secureFilename;

    // Create directory if it doesn't exist
    if (!is_dir($destination)) {
        mkdir($destination, 0755, true);
    }

    // Move uploaded file
    if (move_uploaded_file($file['tmp_name'], $fullPath)) {
        return ['success' => true, 'filename' => $secureFilename, 'path' => $fullPath];
    }

    return ['success' => false, 'message' => 'Upload failed'];
}

// Log security events
function logSecurityEvent($event, $details = []) {
    $logEntry = sprintf(
        "[%s] %s: %s - IP: %s - User: %s\n",
        date('Y-m-d H:i:s'),
        $event,
        json_encode($details),
        $_SERVER['REMOTE_ADDR'] ?? 'unknown',
        $_SESSION['username'] ?? 'guest'
    );

    error_log($logEntry, 3, '../logs/security.log');
}

// Rate limiting check
function checkRateLimit($key, $maxRequests, $timeWindow) {
    $cacheKey = "rate_limit_{$key}";
    // In a production environment, use Redis or similar
    // For now, we'll use session-based limiting
    if (!isset($_SESSION[$cacheKey])) {
        $_SESSION[$cacheKey] = ['count' => 1, 'reset_time' => time() + $timeWindow];
        return true;
    }

    if (time() > $_SESSION[$cacheKey]['reset_time']) {
        $_SESSION[$cacheKey] = ['count' => 1, 'reset_time' => time() + $timeWindow];
        return true;
    }

    if ($_SESSION[$cacheKey]['count'] >= $maxRequests) {
        return false;
    }

    $_SESSION[$cacheKey]['count']++;
    return true;
}

// SQL injection prevention (additional layer)
function prepareSecureQuery($pdo, $query, $params = []) {
    $stmt = $pdo->prepare($query);
    $stmt->execute($params);
    return $stmt;
}

// XSS prevention for output
function secureOutput($data) {
    if (is_array($data)) {
        return array_map('secureOutput', $data);
    }
    return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
}

// Secure random string generation
function generateSecureToken($length = 32) {
    return bin2hex(random_bytes($length / 2));
}

// Check if request is HTTPS
function isHTTPS() {
    return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ||
           (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443);
}

// Force HTTPS in production
function enforceHTTPS() {
    if (!isHTTPS() && getenv('APP_ENV') === 'production') {
        header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
        exit;
    }
}

// Initialize security measures
function initSecurity() {
    // Set security headers
    header('X-Frame-Options: DENY');
    header('X-Content-Type-Options: nosniff');
    header('X-XSS-Protection: 1; mode=block');
    header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
    header('Referrer-Policy: strict-origin-when-cross-origin');

    // Prevent clickjacking
    header('X-Frame-Options: SAMEORIGIN');

    // Content Security Policy (basic)
    header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'");

    // Regenerate session ID periodically
    if (!isset($_SESSION['created_at'])) {
        $_SESSION['created_at'] = time();
    } elseif (time() - $_SESSION['created_at'] > SESSION_REGENERATE_INTERVAL) {
        session_regenerate_id(true);
        $_SESSION['created_at'] = time();
    }
}