<?php

/**
 * Система ізоляції тем
 *
 * Забезпечує, щоб теми не могли напряму звертатися до ядра та плагінів.
 * Всі взаємодії повинні відбуватися через хуки та фільтри.
 *
 * @package Flowaxy\Support\Isolation
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Support\Isolation;

final class ThemeIsolation
{
    /**
     * @var string Коренева директорія проекту
     */
    private static string $projectRoot = '';

    /**
     * @var string Директорія ядра
     */
    private static string $engineDir = '';

    /**
     * @var string Директорія тем
     */
    private static string $themesDir = '';

    /**
     * @var string Директорія плагінів
     */
    private static string $pluginsDir = '';

    /**
     * @var bool Чи увімкнена ізоляція
     */
    private static bool $isolationEnabled = true;

    /**
     * Ініціалізація системи ізоляції
     *
     * @param string $projectRoot Коренева директорія проекту
     * @return void
     */
    public static function initialize(string $projectRoot): void
    {
        self::$projectRoot = rtrim($projectRoot, '/\\') . DS;
        self::$engineDir = self::$projectRoot . 'flowaxy' . DS;
        self::$themesDir = self::$projectRoot . 'themes' . DS;
        self::$pluginsDir = self::$projectRoot . 'plugins' . DS;
    }

    /**
     * Увімкнути/вимкнути ізоляцію
     *
     * @param bool $enabled
     * @return void
     */
    public static function setEnabled(bool $enabled): void
    {
        self::$isolationEnabled = $enabled;
    }

    /**
     * Перевірка, чи увімкнена ізоляція
     *
     * @return bool
     */
    public static function isEnabled(): bool
    {
        return self::$isolationEnabled;
    }

    /**
     * Перевірка, чи шлях знаходиться в межах дозволеної директорії теми
     *
     * @param string $filePath Шлях до файлу
     * @param string $themeDir Директорія теми
     * @return bool
     */
    public static function isPathAllowed(string $filePath, string $themeDir): bool
    {
        if (!self::$isolationEnabled) {
            return true;
        }

        $realFilePath = realpath($filePath);
        $realThemeDir = realpath($themeDir);

        if ($realFilePath === false || $realThemeDir === false) {
            return false;
        }

        // Шлях повинен бути всередині директорії теми
        return str_starts_with($realFilePath, $realThemeDir);
    }

    /**
     * Перевірка, чи шлях належить до ядра
     *
     * @param string $filePath Шлях до файлу
     * @return bool
     */
    public static function isEnginePath(string $filePath): bool
    {
        if (empty(self::$engineDir)) {
            return false;
        }

        $realFilePath = realpath($filePath);
        $realEngineDir = realpath(self::$engineDir);

        if ($realFilePath === false || $realEngineDir === false) {
            return false;
        }

        return str_starts_with($realFilePath, $realEngineDir);
    }

    /**
     * Перевірка, чи шлях належить до плагінів
     *
     * @param string $filePath Шлях до файлу
     * @return bool
     */
    public static function isPluginPath(string $filePath): bool
    {
        if (empty(self::$pluginsDir)) {
            return false;
        }

        $realFilePath = realpath($filePath);
        $realPluginsDir = realpath(self::$pluginsDir);

        if ($realFilePath === false || $realPluginsDir === false) {
            return false;
        }

        return str_starts_with($realFilePath, $realPluginsDir);
    }

    /**
     * Блокування доступу до файлу ядра або плагіна
     *
     * @param string $filePath Шлях до файлу
     * @param string $themeDir Директорія теми
     * @return void
     * @throws \RuntimeException Якщо доступ заборонено
     */
    public static function blockAccess(string $filePath, string $themeDir): void
    {
        if (!self::$isolationEnabled) {
            return;
        }

        // Перевіряємо, чи шлях дозволений для теми
        if (self::isPathAllowed($filePath, $themeDir)) {
            return;
        }

        // Блокуємо доступ до ядра
        if (self::isEnginePath($filePath)) {
            throw new \RuntimeException(
                "Тема не може напряму звертатися до файлів ядра. " .
                "Використовуйте хуки та фільтри для взаємодії з системою."
            );
        }

        // Блокуємо доступ до плагінів
        if (self::isPluginPath($filePath)) {
            throw new \RuntimeException(
                "Тема не може напряму звертатися до файлів плагінів. " .
                "Використовуйте хуки та фільтри для взаємодії з плагінами."
            );
        }
    }
}
