<?php

declare(strict_types=1);

namespace App\Framework\Mcp\Console;

use App\Framework\Console\ConsoleCommand;
use App\Framework\Console\ConsoleInput;
use App\Framework\Console\ConsoleOutput;
use App\Framework\Console\ExitCode;
use App\Framework\DI\Container;
use App\Framework\Mcp\McpServer;

final readonly class McpServerCommand
{
    public function __construct(
        private Container $container
    ) {
    }

    #[ConsoleCommand(name: 'mcp:server', description: 'Start MCP (Model Context Protocol) server for STDIO communication')]
    public function execute(ConsoleInput $input, ConsoleOutput $output): ExitCode
    {
        // Disable all output buffering and debug output for clean JSON-RPC
        \App\Framework\OutputBuffer\OutputBuffer::cleanAll();

        // Disable terminal control sequences
        putenv('TERM=dumb');

        // Redirect all further output to STDERR except our JSON responses
        ini_set('log_errors', '1');
        ini_set('error_log', 'php://stderr');

        // Log to STDERR so it doesn't interfere with JSON-RPC on STDOUT
        error_log('Starting MCP Server...');

        try {
            $mcpServer = $this->container->get(McpServer::class);

            error_log('MCP Server ready. Listening for JSON-RPC requests on STDIN.');

            // Read from STDIN and process requests
            while (($line = fgets(STDIN)) !== false) {
                $line = trim($line);

                if (empty($line)) {
                    continue;
                }

                try {
                    $response = $mcpServer->handleRequest($line);
                    echo $response . "\n";
                    flush();
                } catch (\Throwable $e) {
                    // Extract request ID if possible for error response
                    $requestId = null;

                    try {
                        $request = json_decode($line, true);
                        $requestId = $request['id'] ?? null;
                    } catch (\Throwable) {
                        // Ignore JSON decode errors
                    }

                    $errorResponse = json_encode([
                        'jsonrpc' => '2.0',
                        'error' => [
                            'code' => -32603,
                            'message' => 'Internal error: ' . $e->getMessage(),
                        ],
                        'id' => $requestId,
                    ]);
                    echo $errorResponse . "\n";
                    flush();
                }
            }

            return ExitCode::SUCCESS;

        } catch (\Throwable $e) {
            error_log('Failed to start MCP server: ' . $e->getMessage());

            return ExitCode::GENERAL_ERROR;
        }
    }
}
