<?php

declare(strict_types=1);

if (! function_exists('adCas2ContentTypeByPath')) {
    function adCas2ContentTypeByPath(string $path): ?string
    {
        $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));

        return match ($ext) {
            'css' => 'text/css; charset=UTF-8',
            'js', 'mjs' => 'application/javascript; charset=UTF-8',
            'json', 'map' => 'application/json; charset=UTF-8',
            'html', 'htm' => 'text/html; charset=UTF-8',
            'txt' => 'text/plain; charset=UTF-8',
            'svg' => 'image/svg+xml; charset=UTF-8',
            'ico' => 'image/x-icon',
            'png' => 'image/png',
            'jpg', 'jpeg' => 'image/jpeg',
            'gif' => 'image/gif',
            'webp' => 'image/webp',
            'woff' => 'font/woff',
            'woff2' => 'font/woff2',
            'ttf' => 'font/ttf',
            'otf' => 'font/otf',
            'wasm' => 'application/wasm',
            default => null,
        };
    }
}

if (! function_exists('adCas2LatestMtime')) {
    function adCas2LatestMtime(string $path, array $extensions = []): int
    {
        if (is_file($path)) {
            return (int) filemtime($path);
        }

        if (! is_dir($path)) {
            return 0;
        }

        $latest = 0;
        $allowed = array_map(static fn (string $item): string => strtolower(ltrim($item, '.')), $extensions);
        $hasFilter = count($allowed) > 0;

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

        /** @var SplFileInfo $file */
        foreach ($iterator as $file) {
            if (! $file->isFile()) {
                continue;
            }

            if ($hasFilter) {
                $ext = strtolower((string) $file->getExtension());
                if (! in_array($ext, $allowed, true)) {
                    continue;
                }
            }

            $mtime = (int) $file->getMTime();
            if ($mtime > $latest) {
                $latest = $mtime;
            }
        }

        return $latest;
    }
}

if (! function_exists('adCas2FrontendDistStaleStatus')) {
    /**
     * Detect stale frontend dist in local integration environment.
     *
     * Result example:
     * [
     *   'is_stale' => true,
     *   'source_mtime' => 1714032000,
     *   'dist_mtime' => 1714031000,
     *   'source_readable' => '2026-04-25 10:14:46',
     *   'dist_readable' => '2026-04-25 09:59:10',
     * ]
     */
    function adCas2FrontendDistStaleStatus(string $webRoot, string $distDir): array
    {
        static $cache = null;
        static $checkedAt = 0.0;

        $now = microtime(true);
        if ($cache !== null && ($now - $checkedAt) < 2.0) {
            return $cache;
        }

        $sourceTargets = [
            $webRoot.'/index.html',
            $webRoot.'/package.json',
            $webRoot.'/vite.config.ts',
            $webRoot.'/src',
        ];

        $sourceMtime = 0;
        foreach ($sourceTargets as $target) {
            $mtime = str_ends_with($target, '/src')
                ? adCas2LatestMtime($target, ['ts', 'tsx', 'js', 'jsx', 'vue', 'css', 'scss', 'json'])
                : adCas2LatestMtime($target);
            if ($mtime > $sourceMtime) {
                $sourceMtime = $mtime;
            }
        }

        $distMtime = max(
            adCas2LatestMtime($distDir.'/index.html'),
            adCas2LatestMtime($distDir.'/assets', ['js', 'css', 'json', 'map'])
        );

        $isStale = $sourceMtime > 0 && $distMtime > 0 && $sourceMtime > $distMtime;

        $cache = [
            'is_stale' => $isStale,
            'source_mtime' => $sourceMtime,
            'dist_mtime' => $distMtime,
            'source_readable' => $sourceMtime > 0 ? date('Y-m-d H:i:s', $sourceMtime) : null,
            'dist_readable' => $distMtime > 0 ? date('Y-m-d H:i:s', $distMtime) : null,
        ];
        $checkedAt = $now;

        return $cache;
    }
}

$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
$requestPath = parse_url($requestUri, PHP_URL_PATH);
$requestPath = is_string($requestPath) && $requestPath !== '' ? $requestPath : '/';

$projectRoot = __DIR__;
$apiEntrypoint = $projectRoot.'/perf-platform-api/public/index.php';
$webRoot = $projectRoot.'/perf-platform-web';
$webDistDir = $projectRoot.'/perf-platform-web/dist';
$webPublicDir = $projectRoot.'/perf-platform-web/public';

$isApiRequest = $requestPath === '/api'
    || str_starts_with($requestPath, '/api/')
    || $requestPath === '/up';

if (PHP_SAPI === 'cli' && getenv('AD_CAS2_ENTRYPOINT_PROBE') === '1') {
    $staleStatus = adCas2FrontendDistStaleStatus($webRoot, $webDistDir);

    return [
        'request_path' => $requestPath,
        'is_api_request' => $isApiRequest,
        'api_entrypoint' => $apiEntrypoint,
        'web_index' => $webDistDir.'/index.html',
        'frontend_dist_stale' => $staleStatus['is_stale'],
        'frontend_source_mtime' => $staleStatus['source_readable'],
        'frontend_dist_mtime' => $staleStatus['dist_readable'],
        'mime_probe' => [
            'css' => adCas2ContentTypeByPath('/assets/app.css'),
            'js' => adCas2ContentTypeByPath('/assets/app.js'),
            'svg' => adCas2ContentTypeByPath('/assets/logo.svg'),
        ],
    ];
}

$serveStatic = static function (string $baseDir, string $path): bool {
    $normalized = ltrim($path, '/');
    if ($normalized === '') {
        return false;
    }

    $target = realpath($baseDir.DIRECTORY_SEPARATOR.$normalized);
    $base = realpath($baseDir);
    if (! $target || ! $base || ! str_starts_with($target, $base) || ! is_file($target)) {
        return false;
    }

    $mime = adCas2ContentTypeByPath($target);
    if (! $mime) {
        $detected = mime_content_type($target);
        $mime = is_string($detected) && $detected !== '' ? $detected : 'application/octet-stream';
    }

    header('X-Content-Type-Options: nosniff');
    header('Content-Type: '.$mime);
    readfile($target);

    return true;
};

if ($isApiRequest) {
    if (! is_file($apiEntrypoint)) {
        http_response_code(500);
        header('Content-Type: text/plain; charset=UTF-8');
        echo 'API entrypoint not found: '.$apiEntrypoint;

        return;
    }

    require $apiEntrypoint;

    return;
}

$allowStaleDist = getenv('AD_CAS2_ALLOW_STALE_DIST') === '1';
$staleStatus = adCas2FrontendDistStaleStatus($webRoot, $webDistDir);
if (! $allowStaleDist && ($staleStatus['is_stale'] ?? false)) {
    http_response_code(503);
    header('Content-Type: text/plain; charset=UTF-8');
    echo "Frontend dist is stale.\n";
    echo "Source mtime: ".($staleStatus['source_readable'] ?? '-')."\n";
    echo "Dist mtime: ".($staleStatus['dist_readable'] ?? '-')."\n";
    echo "Run: cd perf-platform-web && npm run build\n";
    echo "Temporary bypass: set AD_CAS2_ALLOW_STALE_DIST=1\n";

    return;
}

if ($serveStatic($webDistDir, $requestPath) || $serveStatic($webPublicDir, $requestPath)) {
    return;
}

$spaIndex = $webDistDir.'/index.html';
if (is_file($spaIndex)) {
    header('Content-Type: text/html; charset=UTF-8');
    readfile($spaIndex);

    return;
}

http_response_code(503);
header('Content-Type: text/plain; charset=UTF-8');
echo "Frontend dist not found.\n";
echo "Run: cd perf-platform-web && npm run build\n";
