<?php

if (!function_exists('audit_start_session')) {
    function audit_start_session(): void
    {
        if (session_status() !== PHP_SESSION_NONE || headers_sent()) {
            return;
        }

        $sessionConfig = __DIR__ . '/../magic/session_config.php';
        if (is_file($sessionConfig)) {
            require_once $sessionConfig;
            if (function_exists('bdr_start_session')) {
                bdr_start_session();
                return;
            }
        }

        session_start();
    }
}

if (!function_exists('audit_client_ip')) {
    function audit_client_ip(): string
    {
        $keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR');
        foreach ($keys as $key) {
            if (empty($_SERVER[$key])) {
                continue;
            }

            $value = (string) $_SERVER[$key];
            if ($key === 'HTTP_X_FORWARDED_FOR') {
                $parts = explode(',', $value);
                $value = trim($parts[0]);
            }

            if ($value !== '') {
                return substr($value, 0, 45);
            }
        }

        return 'CLI';
    }
}

if (!function_exists('audit_request_uri')) {
    function audit_request_uri(): string
    {
        if (!empty($_SERVER['REQUEST_URI'])) {
            return substr((string) $_SERVER['REQUEST_URI'], 0, 1000);
        }

        if (!empty($_SERVER['SCRIPT_NAME'])) {
            return substr((string) $_SERVER['SCRIPT_NAME'], 0, 1000);
        }

        return 'CLI';
    }
}

if (!function_exists('audit_user_context')) {
    function audit_user_context(): array
    {
        audit_start_session();

        $userId = isset($_SESSION['user_id']) ? (string) $_SESSION['user_id'] : '';
        $userName = isset($_SESSION['realName']) ? (string) $_SESSION['realName'] : '';

        if ($userName === '' && $userId !== '') {
            $userName = 'User #' . $userId;
        }

        if ($userName === '') {
            $userName = 'غير معروف';
        }

        return array(
            'user_id' => $userId,
            'user_name' => $userName,
            'ip' => audit_client_ip(),
            'request_uri' => audit_request_uri(),
        );
    }
}

if (!function_exists('audit_set_pdo_context')) {
    function audit_set_pdo_context(PDO $pdo): void
    {
        $context = audit_user_context();

        try {
            $stmt = $pdo->prepare(
                'SET @audit_user_id = :user_id,
                     @audit_user_name = :user_name,
                     @audit_ip = :ip,
                     @audit_request_uri = :request_uri'
            );
            $stmt->execute(array(
                ':user_id' => $context['user_id'],
                ':user_name' => $context['user_name'],
                ':ip' => $context['ip'],
                ':request_uri' => $context['request_uri'],
            ));
        } catch (Throwable $e) {
            error_log('Audit context was not applied: ' . $e->getMessage());
        }
    }
}

if (!function_exists('audit_set_mysqli_context')) {
    function audit_set_mysqli_context(mysqli $connection): void
    {
        $context = audit_user_context();

        try {
            $stmt = $connection->prepare(
                'SET @audit_user_id = ?,
                     @audit_user_name = ?,
                     @audit_ip = ?,
                     @audit_request_uri = ?'
            );
            if ($stmt) {
                $stmt->bind_param(
                    'ssss',
                    $context['user_id'],
                    $context['user_name'],
                    $context['ip'],
                    $context['request_uri']
                );
                $stmt->execute();
                $stmt->close();
            }
        } catch (Throwable $e) {
            error_log('Audit context was not applied: ' . $e->getMessage());
        }
    }
}
