using ClaudeDo.Worker.External;
using ModelContextProtocol;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;

namespace ClaudeDo.Worker.Tests.External;

public sealed class ExternalMcpExceptionFilterTests
{
    [Fact]
    public async Task Wrap_TranslatesInvalidOperationException_PreservingMessage()
    {
        McpRequestHandler<CallToolRequestParams, CallToolResult> next =
            (_, _) => throw new InvalidOperationException("Task abc123 not found.");
        var wrapped = ExternalMcpExceptionFilter.Wrap(next);

        var ex = await Assert.ThrowsAsync<McpException>(
            () => wrapped(null!, CancellationToken.None).AsTask());

        Assert.Equal("Task abc123 not found.", ex.Message);
    }

    [Fact]
    public async Task Wrap_TranslatesArgumentException_PreservingMessage()
    {
        McpRequestHandler<CallToolRequestParams, CallToolResult> next =
            (_, _) => throw new ArgumentException("Unknown model alias 'gpt4'.");
        var wrapped = ExternalMcpExceptionFilter.Wrap(next);

        var ex = await Assert.ThrowsAsync<McpException>(
            () => wrapped(null!, CancellationToken.None).AsTask());

        Assert.Equal("Unknown model alias 'gpt4'.", ex.Message);
    }

    [Fact]
    public async Task Wrap_PassesThroughSuccessfulResult()
    {
        var expected = new CallToolResult();
        McpRequestHandler<CallToolRequestParams, CallToolResult> next =
            (_, _) => ValueTask.FromResult(expected);
        var wrapped = ExternalMcpExceptionFilter.Wrap(next);

        var result = await wrapped(null!, CancellationToken.None);

        Assert.Same(expected, result);
    }
}
