using System.Net;
using System.Net.Http;
using System.Text;
using Xunit;
using Neta.Tray;

public class StatusClientTests
{
    [Fact]
    public async Task GetStatusAsync_reads_runtime_url_from_runtime_info_base_url()
    {
        var runtime = new RuntimeBootstrapInfo
        {
            ControlBaseUrl = "http://127.0.0.1:8011/base/runtime",
            ControlSecret = "secret"
        };
        var handler = new FakeHandler(_ => new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StringContent("{\"data\":{\"ready\":true,\"port\":8011,\"url\":\"http://127.0.0.1:8011\",\"controlBaseUrl\":\"http://127.0.0.1:8011/base/runtime\"}}", Encoding.UTF8, "application/json")
        });
        var client = new StatusClient(new HttpClient(handler));

        var status = await client.GetStatusAsync(runtime, CancellationToken.None);

        Assert.NotNull(status);
        Assert.Equal(8011, status!.Port);
        Assert.Equal("http://127.0.0.1:8011", status.Url);
    }

    [Fact]
    public async Task StopAsync_uses_runtime_info_control_base_url()
    {
        HttpRequestMessage? captured = null;
        var runtime = new RuntimeBootstrapInfo
        {
            ControlBaseUrl = "http://127.0.0.1:8011/base/runtime",
            ControlSecret = "secret"
        };
        var handler = new FakeHandler(request =>
        {
            captured = request;
            return new HttpResponseMessage(HttpStatusCode.OK);
        });
        var client = new StatusClient(new HttpClient(handler));

        await client.StopAsync(runtime, CancellationToken.None);

        Assert.NotNull(captured);
        Assert.Equal(HttpMethod.Post, captured!.Method);
        Assert.Equal("http://127.0.0.1:8011/base/runtime/stop", captured.RequestUri!.ToString());
        Assert.True(captured.Headers.Contains("x-neta-tray-secret"));
    }
}

file sealed class FakeHandler(Func<HttpRequestMessage, HttpResponseMessage> callback) : HttpMessageHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        => Task.FromResult(callback(request));
}
