#!/usr/bin/env php
<?php

declare(strict_types=1);

use KingCMS\Api\ApiTokens;
use KingCMS\Database\Connection;
use KingCMS\Database\Migrator;
use KingCMS\Mcp\Server;
use KingCMS\Mcp\Tools;
use KingCMS\Modules\ModuleRegistry;
use KingCMS\Security\SecretBox;
use KingCMS\Settings;

$autoload = __DIR__ . '/../vendor/autoload.php';
if (is_file($autoload)) {
    require $autoload;
} else {
    spl_autoload_register(static function (string $class): void {
        $prefixes = [
            'KingCMS\\Modules\\Shop\\' => __DIR__ . '/../modules/shop/src/',
            'KingCMS\\' => __DIR__ . '/../app/',
        ];

        foreach ($prefixes as $prefix => $directory) {
            if (strncmp($class, $prefix, strlen($prefix)) !== 0) {
                continue;
            }

            $relative = substr($class, strlen($prefix));
            $file = $directory . str_replace('\\', '/', $relative) . '.php';
            if (is_file($file)) {
                require $file;
            }

            return;
        }
    });
}

// stdout 只能输出 JSON-RPC 消息，诊断信息一律走 stderr。
ini_set('display_errors', 'stderr');
ini_set('log_errors', '0');
error_reporting(E_ALL);

$dataDir = getenv('KINGCMS_DATA_DIR');
if (!is_string($dataDir) || trim($dataDir) === '') {
    $dataDir = __DIR__ . '/../data';
}
$dataDir = rtrim($dataDir, '/');

try {
    $pdo = Connection::get($dataDir . '/kingcms.sqlite');

    $migrator = new Migrator($pdo, __DIR__ . '/../app/Database/migrations');
    $migrator->run();

    $modulesDir = __DIR__ . '/../modules';
    $registry = new ModuleRegistry($pdo, $modulesDir);
    $migrator->runModules($modulesDir, array_keys($registry->installed()));

    $settings = new Settings(
        $pdo,
        new SecretBox(SecretBox::loadOrCreateKey($dataDir . '/app.key'))
    );

    // 所有工具都按 API 令牌的作用域授权；没有有效令牌时 tools/list 为空，调用一律拒绝。
    $token = null;
    $rawToken = getenv('KINGCMS_API_TOKEN');
    if (is_string($rawToken) && trim($rawToken) !== '') {
        $tokens = new ApiTokens($pdo);
        $row = $tokens->findByToken(trim($rawToken));
        if ($row !== null && ApiTokens::isActive($row)) {
            $token = $row;
            $tokens->touch((int) $row['id']);
        } else {
            fwrite(STDERR, 'KINGCMS_API_TOKEN 无效、已禁用或已过期，MCP 工具不可用。' . PHP_EOL);
        }
    }

    $server = new Server(new Tools($pdo, $settings, null, $token));

    while (($line = fgets(STDIN)) !== false) {
        $response = $server->handleLine($line);
        if ($response === null) {
            continue;
        }

        fwrite(STDOUT, $response . "\n");
        fflush(STDOUT);
    }
} catch (Throwable $exception) {
    fwrite(STDERR, 'MCP 服务启动或运行失败：' . $exception->getMessage() . PHP_EOL);
    exit(1);
}
