<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Bootstrap;

final class PlatformBootstrapLoader
{
    /** @var array<string, bool> */
    private static array $loaded = [];

    /**
     * Bootstraps PPphp source files in dependency-safe order.
     *
     * This is intentionally local-first and Composer-independent so existing
     * PPphp tools/tests can run before Composer autoload is introduced.
     */
    public static function load(string $basePath): void
    {
        $basePath = rtrim($basePath, DIRECTORY_SEPARATOR);

        foreach (self::orderedFiles() as $relative) {
            self::requireFile($basePath . $relative);
        }

        self::loadDirectory($basePath . '/core/Platform/Compatibility');
        self::loadDirectory($basePath . '/core/Platform/Manifest');
        self::loadDirectory($basePath . '/core/Platform/Modules');
        self::loadDirectory($basePath . '/core/Platform/Extensions');
        self::loadDirectory($basePath . '/core/Platform/Kernel');
    }

    private static function requireFile(string $path): void
    {
        if (!is_file($path)) {
            return;
        }

        $real = realpath($path) ?: $path;

        if (isset(self::$loaded[$real])) {
            return;
        }

        require_once $real;
        self::$loaded[$real] = true;
    }

    private static function loadDirectory(string $directory): void
    {
        if (!is_dir($directory)) {
            return;
        }

        $files = [];

        $iterator = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS)
        );

        foreach ($iterator as $file) {
            if (!$file instanceof \SplFileInfo || !$file->isDir() && strtolower($file->getExtension()) === 'php') {
                if ($file instanceof \SplFileInfo && $file->isFile() && strtolower($file->getExtension()) === 'php') {
                    $files[] = $file->getPathname();
                }
            }
        }

        sort($files);

        foreach ($files as $file) {
            self::requireFile($file);
        }
    }

    /**
     * @return string[]
     */
    private static function orderedFiles(): array
    {
        return [
            '/core/Platform/Foundation/PlatformIdentity.php',
            '/core/Platform/Foundation/PlatformVersion.php',
            '/core/Platform/Foundation/PlatformMetadata.php',
            '/core/Platform/Foundation/PlatformObject.php',
            '/core/Platform/Foundation/AbstractPlatformObject.php',
            '/core/Platform/Foundation/PlatformCollection.php',
            '/core/Platform/Foundation/PlatformSerializer.php',
            '/core/Platform/Foundation/PlatformValidator.php',

            '/core/Platform/Services/Contracts/CapabilityInterface.php',
            '/core/Platform/Services/Contracts/DescriptorInterface.php',
            '/core/Platform/Services/Contracts/RegistryInterface.php',
            '/core/Platform/Services/Contracts/ServiceFactoryInterface.php',
            '/core/Platform/Services/Contracts/ServiceLocatorInterface.php',
            '/core/Platform/Services/Contracts/ServiceInterface.php',
            '/core/Platform/Services/Contracts/ServiceProviderInterface.php',
            '/core/Platform/Services/Contracts/ServiceRegistryInterface.php',

            '/core/Platform/Services/Metadata/CapabilityMetadata.php',
            '/core/Platform/Services/Metadata/ServiceDependency.php',
            '/core/Platform/Services/Metadata/ServiceAlias.php',
            '/core/Platform/Services/Metadata/ServiceTag.php',
            '/core/Platform/Services/Metadata/ServiceMetadata.php',
            '/core/Platform/Services/Metadata/MetadataFactory.php',

            '/core/Platform/Services/Definition/ServiceDefinition.php',

            '/core/Platform/Services/Descriptor/ServiceDescriptor.php',
            '/core/Platform/Services/Descriptor/DescriptorFactory.php',
            '/core/Platform/Services/Descriptor/DescriptorCollection.php',
            '/core/Platform/Services/Descriptor/DescriptorValidator.php',

            '/core/Platform/Services/Blueprint/BlueprintInterface.php',
            '/core/Platform/Services/Blueprint/ServiceBlueprint.php',
            '/core/Platform/Services/Blueprint/BlueprintBuilder.php',
            '/core/Platform/Services/Blueprint/BlueprintFactory.php',
            '/core/Platform/Services/Blueprint/BlueprintCollection.php',
            '/core/Platform/Services/Blueprint/BlueprintValidator.php',

            '/core/Platform/Services/Registry/ServiceRegistry.php',
            '/core/Platform/Services/Registry/AliasRegistry.php',
            '/core/Platform/Services/Registry/CapabilityRegistry.php',
            '/core/Platform/Services/Registry/RegistryCollection.php',

            '/core/Platform/Services/Container/ServiceContainer.php',
            '/core/Platform/Services/Container/PlatformServiceHub.php',

            '/core/Platform/Runtime/RuntimeConfiguration.php',
            '/core/Platform/Runtime/RuntimeEnvironment.php',
            '/core/Platform/Runtime/RuntimeState.php',
            '/core/Platform/Runtime/PlatformRuntimeContext.php',
            '/core/Platform/Runtime/PlatformRuntimeBootstrap.php',
            '/core/Platform/Runtime/ManifestServiceLoader.php',
            '/core/Platform/Runtime/ManifestRuntimeBootstrap.php',
        ];
    }
}
