<?php

declare(strict_types=1);

namespace Flowaxy\Bootstrap;

use Flowaxy\Core\Contracts\ContainerInterface;
use Flowaxy\Core\Contracts\KernelInterface;
use Flowaxy\Core\System\Kernel\CliKernel;
use Flowaxy\Core\System\Kernel\HttpKernel;
use Flowaxy\Core\System\PathResolver;

use function interface_exists;
use function class_exists;
use function file_exists;
use function is_readable;
use function defined;

use const DIRECTORY_SEPARATOR;

// Ініціалізатор компонентів застосунку
final class ApplicationInitializer
{
    // Ініціалізація компонентів застосунку та створення відповідного Kernel
    public static function initialize(ContainerInterface $container, bool $isCli): KernelInterface
    {
        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
        $flowaxyDir = PathResolver::flowaxy();

        // Завантажуємо Kernel класи, якщо вони ще не завантажені
        if (!interface_exists('Flowaxy\Core\Contracts\KernelInterface')) {
            $kernelInterfaceFile = $flowaxyDir . $ds . 'Core' . $ds . 'Contracts' . $ds . 'KernelInterface.php';
            if (file_exists($kernelInterfaceFile) && is_readable($kernelInterfaceFile)) {
                require_once $kernelInterfaceFile;
            }
        }

        if (!class_exists('Flowaxy\Core\System\Kernel\Kernel')) {
            $kernelFile = $flowaxyDir . $ds . 'Core' . $ds . 'System' . $ds . 'Kernel' . $ds . 'Kernel.php';
            if (file_exists($kernelFile) && is_readable($kernelFile)) {
                require_once $kernelFile;
            }
        }

        if (!class_exists(CliKernel::class)) {
            $cliKernelFile = $flowaxyDir . $ds . 'Core' . $ds . 'System' . $ds . 'Kernel' . $ds . 'CliKernel.php';
            if (file_exists($cliKernelFile) && is_readable($cliKernelFile)) {
                require_once $cliKernelFile;
            }
        }

        if (!class_exists(HttpKernel::class)) {
            $httpKernelFile = $flowaxyDir . $ds . 'Core' . $ds . 'System' . $ds . 'Kernel' . $ds . 'HttpKernel.php';
            if (file_exists($httpKernelFile) && is_readable($httpKernelFile)) {
                require_once $httpKernelFile;
            }
        }

        $rootDir = PathResolver::root();

        if ($isCli) {
            $argv = $GLOBALS['argv'] ?? $_SERVER['argv'] ?? [];
            return new CliKernel($rootDir, $argv);
        }

        return new HttpKernel($rootDir);
    }
}
