using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using PolyTrader.Modules.Supervisor.Agent;
using PolyTrader.Modules.Supervisor.Mcp;
using PolyTraderSharp.Services;
using Xunit;

namespace PolyTrader.Tests
{
    /// <summary>End-to-End-Test des MCP-Light-HTTP-Hosts (echter HttpListener auf 127.0.0.1).</summary>
    public class McpLightServerTests
    {
        [Fact]
        public async Task Server_answers_initialize_and_tools_call_over_http()
        {
            int port = 52000 + new Random().Next(1000, 9000);
            Environment.SetEnvironmentVariable("POLYTRADER_MCP_PORT", port.ToString());
            try
            {
                var reg = new SupervisorToolRegistry();
                reg.Register(new SupervisorTool("echo", "Echo",
                    """{"type":"object","properties":{"text":{"type":"string"}}}""",
                    args => "ECHO:" + (SupervisorToolRegistry.GetString(args, "text") ?? "")));

                var server = new McpLightServer(reg, new TerminalLogger());
                await server.StartAsync(CancellationToken.None);
                await Task.Delay(300);   // Listener-Start abwarten

                using var http = new HttpClient();
                string url = $"http://127.0.0.1:{port}/mcp/";

                // initialize
                var initResp = await http.PostAsync(url, new StringContent(
                    """{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}""", Encoding.UTF8, "application/json"));
                Assert.True(initResp.IsSuccessStatusCode);
                using (var doc = JsonDocument.Parse(await initResp.Content.ReadAsStringAsync()))
                    Assert.Equal(McpJsonRpc.ServerName,
                        doc.RootElement.GetProperty("result").GetProperty("serverInfo").GetProperty("name").GetString());

                // tools/call
                var callResp = await http.PostAsync(url, new StringContent(
                    """{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"echo","arguments":{"text":"mcp"}}}""",
                    Encoding.UTF8, "application/json"));
                using (var doc = JsonDocument.Parse(await callResp.Content.ReadAsStringAsync()))
                    Assert.Equal("ECHO:mcp",
                        doc.RootElement.GetProperty("result").GetProperty("content")[0].GetProperty("text").GetString());

                // Notification -> 202
                var notifyResp = await http.PostAsync(url, new StringContent(
                    """{"jsonrpc":"2.0","method":"notifications/initialized"}""", Encoding.UTF8, "application/json"));
                Assert.Equal(202, (int)notifyResp.StatusCode);

                // GET -> 405 (kein SSE-Stream)
                var getResp = await http.GetAsync(url);
                Assert.Equal(405, (int)getResp.StatusCode);

                await server.StopAsync(CancellationToken.None);
            }
            finally
            {
                Environment.SetEnvironmentVariable("POLYTRADER_MCP_PORT", null);
            }
        }
    }
}
