using System.Text.Json;
using ColaFlow.Modules.Mcp.Contracts.JsonRpc;
using FluentAssertions;

namespace ColaFlow.Modules.Mcp.Tests.Contracts;

/// <summary>
/// Unit tests for JsonRpcResponse
/// </summary>
public class JsonRpcResponseTests
{
    [Fact]
    public void Success_CreatesValidSuccessResponse()
    {
        // Arrange
        var result = new { message = "success" };
        var id = 1;

        // Act
        var response = JsonRpcResponse.Success(result, id);

        // Assert
        response.Should().NotBeNull();
        response.JsonRpc.Should().Be("2.0");
        response.Result.Should().NotBeNull();
        response.Error.Should().BeNull();
        response.Id.Should().Be(id);
    }

    [Fact]
    public void CreateError_CreatesValidErrorResponse()
    {
        // Arrange
        var error = JsonRpcError.InternalError("Test error");
        var id = 1;

        // Act
        var response = JsonRpcResponse.CreateError(error, id);

        // Assert
        response.Should().NotBeNull();
        response.JsonRpc.Should().Be("2.0");
        response.Result.Should().BeNull();
        response.Error.Should().NotBeNull();
        response.Error.Should().Be(error);
        response.Id.Should().Be(id);
    }

    [Fact]
    public void ParseError_CreatesResponseWithNullId()
    {
        // Act
        var response = JsonRpcResponse.ParseError("Invalid JSON");

        // Assert
        response.Error.Should().NotBeNull();
        response.Error!.Code.Should().Be((int)JsonRpcErrorCode.ParseError);
        response.Id.Should().BeNull();
    }

    [Fact]
    public void MethodNotFound_IncludesMethodNameInError()
    {
        // Act
        var response = JsonRpcResponse.MethodNotFound("unknown_method", 1);

        // Assert
        response.Error.Should().NotBeNull();
        response.Error!.Code.Should().Be((int)JsonRpcErrorCode.MethodNotFound);
        response.Error.Message.Should().Contain("unknown_method");
    }

    [Fact]
    public void Serialize_SuccessResponse_DoesNotIncludeError()
    {
        // Arrange
        var response = JsonRpcResponse.Success(new { result = "ok" }, 1);

        // Act
        var json = JsonSerializer.Serialize(response, new JsonSerializerOptions
        {
            DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
        });

        // Assert
        json.Should().Contain("\"result\":");
        json.Should().NotContain("\"error\":");
    }

    [Fact]
    public void Serialize_ErrorResponse_DoesNotIncludeResult()
    {
        // Arrange
        var response = JsonRpcResponse.CreateError(JsonRpcError.InternalError(), 1);

        // Act
        var json = JsonSerializer.Serialize(response, new JsonSerializerOptions
        {
            DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
        });

        // Assert
        json.Should().Contain("\"error\":");
        json.Should().NotContain("\"result\":");
    }
}
