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

declare(strict_types=1);

spl_autoload_register(static function (string $class): void {
    $prefixes = [
        'Archetern\\Kernel\\' => __DIR__ . '/../../archetern-kernel/src/',
        'Archetern\\CLI\\' => __DIR__ . '/../src/',
        'Archetern\\Bridge\\' => __DIR__ . '/../../archetern-bridge/src/',
        'Archetern\\AI\\' => __DIR__ . '/../../archetern-ai/src/',
        'Archetern\\Security\\' => __DIR__ . '/../../archetern-security/src/',
    ];

    foreach ($prefixes as $prefix => $base) {
        if (!str_starts_with($class, $prefix)) {
            continue;
        }

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

use Archetern\CLI\Bootstrap\ArcheternCliBootstrap;
use Archetern\Kernel\Console\BufferedOutput;
use Archetern\Kernel\Console\ConsoleInput;
use Archetern\Kernel\Console\ExitCode;
use Archetern\Kernel\Console\StreamOutput;

function archeternCliWantsJson(array $argv): bool
{
    foreach (array_slice($argv, 1) as $token) {
        if ($token === '--json' || str_starts_with((string) $token, '--json=')) {
            return true;
        }
    }

    return false;
}

function archeternCliCommandName(array $argv): ?string
{
    foreach (array_slice($argv, 1) as $token) {
        $token = (string) $token;
        if ($token === '' || str_starts_with($token, '-')) {
            continue;
        }

        return $token;
    }

    return null;
}

function archeternCliEmitJson(array $payload): void
{
    fwrite(STDOUT, json_encode($payload, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES) . PHP_EOL);
}

try {
    $bootstrap = ArcheternCliBootstrap::from(getcwd() ?: null);
    $application = $bootstrap->application();
    $input = ConsoleInput::fromArgv($argv);

    if ($input->hasOption('json')) {
        $output = new BufferedOutput();
        $exit = $application->run($input, $output);
        $text = trim($output->contents());
        $decoded = $text === '' ? null : json_decode($text, true);
        if (is_array($decoded) && array_key_exists('ok', $decoded) && array_key_exists('exit_code', $decoded)) {
            // The command already emitted a validated JSON envelope. Preserve
            // JSON object/array distinctions such as MCP inputSchema
            // properties:{} and examples:[{}] instead of assoc-decoding and
            // accidentally re-encoding them as arrays.
            fwrite(STDOUT, $text . PHP_EOL);
        } else {
            archeternCliEmitJson([
                'ok' => $exit === ExitCode::SUCCESS,
                'command' => $input->command(),
                'exit_code' => $exit,
                'data' => ['output' => $text],
            ]);
        }
    } else {
        $exit = $application->run($input, new StreamOutput(STDOUT));
    }
} catch (Throwable $error) {
    if (archeternCliWantsJson($argv)) {
        archeternCliEmitJson([
            'ok' => false,
            'command' => archeternCliCommandName($argv),
            'exit_code' => ExitCode::FAILURE,
            'error' => $error->getMessage(),
        ]);
    } else {
        fwrite(STDERR, 'Archetern CLI error: ' . $error->getMessage() . PHP_EOL);
    }
    $exit = ExitCode::FAILURE;
}

exit($exit);
