<?php
/**
 * Security Configuration for HIPAA Compliance
 * DO NOT commit encryption keys to version control
 * Store in environment variables or secure vault
 */

// Encryption Key (MUST be stored in environment variable in production)
if (!defined('DB_ENCRYPTION_KEY')) {
    define('DB_ENCRYPTION_KEY', getenv('DB_ENCRYPTION_KEY') ?: 'CHANGE_THIS_IN_PRODUCTION_USE_ENV_VAR_32CHARS');
}

// Session Configuration
if (!defined('SESSION_TIMEOUT')) {
    define('SESSION_TIMEOUT', 900); // 15 minutes in seconds (HIPAA requirement)
}

if (!defined('SESSION_WARNING')) {
    define('SESSION_WARNING', 60); // Warn user 60 seconds before timeout
}

// Password Policy (NIST SP 800-63B compliant)
if (!defined('MIN_PASSWORD_LENGTH')) {
    define('MIN_PASSWORD_LENGTH', 12);
}

// Audit Configuration
if (!defined('AUDIT_ENABLED')) {
    define('AUDIT_ENABLED', true);
}

// Data Retention (in days)
if (!defined('CLIENT_DATA_RETENTION_DAYS')) {
    define('CLIENT_DATA_RETENTION_DAYS', 2555); // 7 years (HIPAA requirement)
}

// Breach Notification Settings
if (!defined('BREACH_NOTIFICATION_THRESHOLD')) {
    define('BREACH_NOTIFICATION_THRESHOLD', 500); // HIPAA requires notification if 500+ records affected
}

if (!defined('BREACH_NOTIFICATION_DEADLINE_DAYS')) {
    define('BREACH_NOTIFICATION_DEADLINE_DAYS', 60); // HIPAA requires notification within 60 days
}

/**
 * Initialize database security settings
 * MUST be called before any database operations involving PHI
 */
function initializeDatabaseSecurity($conn, $user_id) {
    // Set encryption key for MySQL AES functions
    $encryption_key = DB_ENCRYPTION_KEY;
    $conn->query("SET @encryption_key = '{$encryption_key}'");
    
    // Set current user for audit triggers
    $conn->query("SET @current_user_id = {$user_id}");
    
    // Set IP address for audit trails
    $ip_address = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
    $conn->query("SET @current_ip_address = '{$ip_address}'");
    
    return true;
}

/**
 * Check if user has permission to access specific PHI fields
 */
function canAccessPHI($conn, $user_id, $resource_type, $field_name = null) {
    $sql = "SELECT COUNT(*) as has_permission 
            FROM role_permissions rp
            JOIN users u ON u.role_id = rp.role_id
            WHERE u.user_id = ? 
            AND rp.resource_type = ?
            AND rp.permission_type = 'READ'
            AND rp.is_active = 1";
    
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("is", $user_id, $resource_type);
    $stmt->execute();
    $result = $stmt->get_result()->fetch_assoc();
    
    return $result['has_permission'] > 0;
}

/**
 * Log PHI access for audit trail
 */
function logPHIAccess($conn, $user_id, $entity_type, $entity_id, $action, $fields_accessed = [], $justification = '') {
    if (!AUDIT_ENABLED) return;
    
    $sql = "INSERT INTO audit_log (
        user_id, action_type, entity_type, entity_id,
        description, ip_address, user_agent,
        old_values, new_values, status, created_at
    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'SUCCESS', NOW())";
    
    $stmt = $conn->prepare($sql);
    
    $description = "Accessed PHI: " . $action;
    if ($justification) {
        $description .= " - Justification: " . $justification;
    }
    
    $ip_address = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
    $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
    $fields_json = json_encode(['fields_accessed' => $fields_accessed]);
    $justification_json = json_encode(['justification' => $justification]);
    
    $stmt->bind_param("isssissss", 
        $user_id, 
        $action, 
        $entity_type, 
        $entity_id,
        $description,
        $ip_address,
        $user_agent,
        $fields_json,
        $justification_json
    );
    
    $stmt->execute();
}

/**
 * Detect potential security incidents
 */
function detectSecurityIncident($conn, $user_id, $incident_type, $description) {
    // Check for multiple failed attempts
    $check_sql = "SELECT COUNT(*) as incident_count 
                  FROM security_incidents 
                  WHERE created_by = ? 
                  AND incident_type = ?
                  AND discovery_date >= DATE_SUB(NOW(), INTERVAL 1 HOUR)";
    
    $stmt = $conn->prepare($check_sql);
    $stmt->bind_param("is", $user_id, $incident_type);
    $stmt->execute();
    $result = $stmt->get_result()->fetch_assoc();
    
    if ($result['incident_count'] >= 3) {
        // Log security incident
        $incident_number = 'SEC-' . date('Ymd') . '-' . str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
        
        $incident_sql = "INSERT INTO security_incidents (
            incident_number, incident_type, severity, status,
            description, discovery_date, discovery_method,
            created_by, created_at
        ) VALUES (?, ?, 'HIGH', 'DETECTED', ?, NOW(), 'AUTOMATED_MONITORING', ?, NOW())";
        
        $stmt2 = $conn->prepare($incident_sql);
        $stmt2->bind_param("sssi", $incident_number, $incident_type, $description, $user_id);
        $stmt2->execute();
        
        // Send notification to security team
        sendSecurityNotification($conn, $incident_number, $incident_type, $description);
    }
}

/**
 * Send security notification
 */
function sendSecurityNotification($conn, $incident_number, $incident_type, $description) {
    $notify_sql = "INSERT INTO compliance_notifications (
        notification_type, recipient_type, recipient_identifier,
        subject, message, urgency, delivery_method, created_by, created_at
    ) VALUES ('VIOLATION_DETECTED', 'ROLE', 'SECURITY_ADMIN', ?, ?, 'HIGH', 'EMAIL', 1, NOW())";
    
    $subject = "Security Incident Detected: {$incident_number}";
    $message = "Incident Type: {$incident_type}\nDescription: {$description}\nTime: " . date('Y-m-d H:i:s');
    
    $stmt = $conn->prepare($notify_sql);
    $stmt->bind_param("ss", $subject, $message);
    $stmt->execute();
}

/**
 * Set security headers (HIPAA compliant)
 */
function setSecurityHeaders() {
    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("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' cdn.jsdelivr.net cdnjs.cloudflare.com code.jquery.com; style-src 'self' 'unsafe-inline' cdn.jsdelivr.net cdnjs.cloudflare.com; img-src 'self' data: https:; font-src 'self' data: cdnjs.cloudflare.com; connect-src 'self';");
    header("Referrer-Policy: strict-origin-when-cross-origin");
    header("Permissions-Policy: geolocation=(), microphone=(), camera=()");
}

/**
 * Validate password complexity (NIST SP 800-63B)
 */
function validatePasswordComplexity($password) {
    $errors = [];
    
    if (strlen($password) < MIN_PASSWORD_LENGTH) {
        $errors[] = "Password must be at least " . MIN_PASSWORD_LENGTH . " characters";
    }
    if (!preg_match('/[A-Z]/', $password)) {
        $errors[] = "Password must contain at least one uppercase letter";
    }
    if (!preg_match('/[a-z]/', $password)) {
        $errors[] = "Password must contain at least one lowercase letter";
    }
    if (!preg_match('/[0-9]/', $password)) {
        $errors[] = "Password must contain at least one number";
    }
    if (!preg_match('/[^A-Za-z0-9]/', $password)) {
        $errors[] = "Password must contain at least one special character";
    }
    
    // Check against common passwords (simplified check)
    $common_passwords = ['password', '12345678', 'qwerty', 'abc123', 'password123', 'admin123'];
    if (in_array(strtolower($password), $common_passwords)) {
        $errors[] = "Password is too common. Please choose a stronger password";
    }
    
    return $errors;
}

/**
 * Check and enforce session timeout
 */
function checkSessionTimeout() {
    if (!isset($_SESSION['user_id'])) {
        return false;
    }
    
    $current_time = time();
    
    if (isset($_SESSION['last_activity']) && 
        ($current_time - $_SESSION['last_activity']) > SESSION_TIMEOUT) {
        
        // Log the timeout
        if (isset($_SESSION['user_id'])) {
            global $conn;
            $user_id = $_SESSION['user_id'];
            $sql = "INSERT INTO audit_log (user_id, action_type, entity_type, description, status, created_at) 
                    VALUES (?, 'LOGOUT', 'session', 'Session expired due to inactivity', 'SUCCESS', NOW())";
            $stmt = $conn->prepare($sql);
            $stmt->bind_param("i", $user_id);
            $stmt->execute();
        }
        
        session_unset();
        session_destroy();
        header('Location: login.php?timeout=1');
        exit();
    }
    
    $_SESSION['last_activity'] = $current_time;
    return true;
}

/**
 * Sanitize input to prevent XSS
 */
function sanitizeInput($data) {
    if (is_array($data)) {
        foreach ($data as $key => $value) {
            $data[$key] = sanitizeInput($value);
        }
        return $data;
    }
    
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
    return $data;
}
?>