using System.Net;

namespace ClawdDotNet.Core.Tests.Infrastructure;

/// <summary>
/// Liefert vorprogrammierte HTTP-Antworten, ohne dass ein Netzwerkzugriff stattfindet.
/// </summary>
internal sealed class FakeHttpMessageHandler : HttpMessageHandler
{
    private readonly Queue<Func<HttpResponseMessage>> _responses = new();

    public int RequestCount { get; private set; }

    public FakeHttpMessageHandler Responds(HttpStatusCode status, string body = "{}", TimeSpan? retryAfter = null)
    {
        _responses.Enqueue(() =>
        {
            var response = new HttpResponseMessage(status)
            {
                Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json")
            };
            if (retryAfter is { } delta)
                response.Headers.RetryAfter = new System.Net.Http.Headers.RetryConditionHeaderValue(delta);
            return response;
        });
        return this;
    }

    public FakeHttpMessageHandler RespondsWithSuccess(string body = """{"id":"x","choices":[]}""")
        => Responds(HttpStatusCode.OK, body);

    public FakeHttpMessageHandler Throws(Exception ex)
    {
        _responses.Enqueue(() => throw ex);
        return this;
    }

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        RequestCount++;

        if (_responses.Count == 0)
            throw new InvalidOperationException(
                $"FakeHttpMessageHandler: unerwartete Anfrage Nr. {RequestCount}.");

        return Task.FromResult(_responses.Dequeue()());
    }
}
