<?php
/**
 * Strict PSR-4 Autoloader for BotFend Anti-Bot Firewall
 *
 * High-performance autoloader with zero regex and zero database calls.
 * Requires strict 1:1 ClassName to FilePath matching.
 *
 * @package BotFend\Core
 */

declare(strict_types=1);

namespace BotFend\Core;

defined('ABSPATH') || exit;

class Autoloader {

    private const NAMESPACE_PREFIX = 'BotFend\\';
    private const BASE_DIR = BOTFEND_PATH;

    /**
     * Strict PSR-4 Namespace to Directory Mapping
     */
    private const NAMESPACE_MAP = [
        'BotFend\\Core\\'         => 'includes/core/',
        'BotFend\\Database\\'     => 'includes/database/',
        'BotFend\\Utilities\\'    => 'includes/utilities/',
        'BotFend\\Logging\\'      => 'includes/logging/',
        'BotFend\\Config\\'       => 'includes/config/',
        'BotFend\\Security\\'     => 'includes/security/',
        'BotFend\\Detection\\'    => 'includes/detection/',
        'BotFend\\Challenges\\'   => 'includes/challenges/',
        'BotFend\\Adaptive\\'     => 'includes/adaptive/',
        'BotFend\\ThirdParty\\'   => 'includes/third-party/',
        'BotFend\\Firewall\\'     => 'includes/firewall/',
        'BotFend\\Cloudflare\\'   => 'includes/cloudflare/',
        'BotFend\\License\\'      => 'includes/license/',        // ADDED
        'BotFend\\Admin\\Pages\\' => 'admin/pages/',
        'BotFend\\Admin\\'        => 'admin/',
    ];

    private static array $loaded_classes = [];
    private static bool $registered = false;
    private static bool $warmed_up = false;
    private static bool $debug_mode = false;

    /**
     * Register the autoloader
     */
    public static function register(): void {
        if (self::$registered) {
            return;
        }

        self::$debug_mode = defined('WP_DEBUG') && WP_DEBUG;
        spl_autoload_register([self::class, 'autoload'], true, true);
        self::$registered = true;
    }

    /**
     * Unregister the autoloader
     */
    public static function unregister(): void {
        spl_autoload_unregister([self::class, 'autoload']);
        self::$registered = false;
    }

    /**
     * Autoload a class strictly using PSR-4 standards (No Regex)
     *
     * @param string $class The fully-qualified class name
     */
    public static function autoload(string $class): void {
        if (isset(self::$loaded_classes[$class])) {
            return;
        }

        if (strpos($class, self::NAMESPACE_PREFIX) !== 0) {
            return;
        }

        self::$loaded_classes[$class] = false;

        foreach (self::NAMESPACE_MAP as $prefix => $base_dir) {
            if (strpos($class, $prefix) === 0) {
                $relative_class = substr($class, strlen($prefix));
                $file = self::BASE_DIR . $base_dir . str_replace('\\', '/', $relative_class) . '.php';

                if (file_exists($file)) {
                    require_once $file;
                    self::$loaded_classes[$class] = true;
                    return;
                }
            }
        }

        if (self::$debug_mode) {
            error_log("BotFend: Failed to load class {$class} strictly.");
        }
    }

    /**
     * Lightweight cache warm-up
     */
    public static function warm_up_cache(): void {
        if (self::$warmed_up) {
            return;
        }

        $core_classes = [
            'BotFend\\Core\\Config',
            'BotFend\\Core\\Core',
            'BotFend\\Database\\Database',
            'BotFend\\Utilities\\Utilities',
            'BotFend\\License\\LicenseKey',           // ADDED
        ];

        if (is_admin()) {
            $core_classes[] = 'BotFend\\Admin\\AdminCoreManager';
            $core_classes[] = 'BotFend\\Admin\\AdminPages';
            $core_classes[] = 'BotFend\\Admin\\AdminSettings';
            $core_classes[] = 'BotFend\\Admin\\Pages\\LicensePage';  // ADDED
        }

        foreach ($core_classes as $class) {
            self::autoload($class);
        }

        self::$warmed_up = true;
    }

    public static function get_loaded_classes(): array {
        return array_keys(array_filter(self::$loaded_classes));
    }

    public static function clear_cache(): void {
        self::$loaded_classes = [];
        self::$warmed_up = false;
    }
}