<?php
declare(strict_types=1);

namespace SafeTun\Backend\Config;

final class ConfigRepository
{
    /** @var array<string,array{mtime:int,sha:string,value:ValidatedConfig}> */
    private static array $cache = [];

    public function __construct(
        private readonly string $configPath,
        private readonly ?string $documentRoot = null,
    ) {
    }

    public function load(): ValidatedConfig
    {
        clearstatcache(true, $this->configPath);
        $mtime = @filemtime($this->configPath);
        $source = @file_get_contents($this->configPath);
        if (!is_int($mtime) || !is_string($source)) {
            throw new \RuntimeException('SafeTun configuration is unavailable.');
        }
        $sha = hash('sha256', $source);
        $cached = self::$cache[$this->configPath] ?? null;
        if ($cached !== null && $cached['mtime'] === $mtime && hash_equals($cached['sha'], $sha)) {
            return $cached['value'];
        }

        // Never include/require config.php. Parse and validate the new bytes completely first.
        $parsed = (new LiteralConfigParser())->parseSource($source, $this->configPath);
        $validated = (new ConfigValidator())->validate($parsed, $this->configPath, $this->documentRoot);
        self::$cache[$this->configPath] = ['mtime' => $mtime, 'sha' => $sha, 'value' => $validated];
        return $validated;
    }

    public static function clearCache(): void
    {
        self::$cache = [];
    }
}
