using ColaFlow.Modules.Mcp.Application.Handlers;
using ColaFlow.Modules.Mcp.Application.Services;
using ColaFlow.Modules.Mcp.Contracts.Resources;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Xunit;

namespace ColaFlow.Modules.Mcp.Tests.Handlers;

public class ResourceHealthCheckHandlerTests
{
    private readonly ILogger<ResourceHealthCheckHandler> _mockLogger;
    private readonly IMcpResourceRegistry _mockRegistry;
    private readonly ResourceHealthCheckHandler _handler;

    public ResourceHealthCheckHandlerTests()
    {
        _mockLogger = Substitute.For<ILogger<ResourceHealthCheckHandler>>();
        _mockRegistry = Substitute.For<IMcpResourceRegistry>();
        _handler = new ResourceHealthCheckHandler(_mockLogger, _mockRegistry);
    }

    [Fact]
    public void MethodName_ShouldBeResourcesHealth()
    {
        // Assert
        _handler.MethodName.Should().Be("resources/health");
    }

    [Fact]
    public async Task HandleAsync_WithHealthyResources_ShouldReturnHealthyStatus()
    {
        // Arrange
        var mockResource = Substitute.For<IMcpResource>();
        mockResource.Uri.Returns("test://resource");
        mockResource.Name.Returns("Test Resource");
        mockResource.Category.Returns("Testing");
        mockResource.GetDescriptor().Returns(new McpResourceDescriptor
        {
            Uri = "test://resource",
            Name = "Test Resource",
            Category = "Testing",
            IsEnabled = true,
            Version = "1.0"
        });

        _mockRegistry.GetAllResources()
            .Returns(new List<IMcpResource> { mockResource }.AsReadOnly());

        // Act
        var result = await _handler.HandleAsync(null, CancellationToken.None);

        // Assert
        result.Should().NotBeNull();
        var response = result as dynamic;
        ((string)response.status).Should().Be("healthy");
        ((int)response.totalResources).Should().Be(1);
        ((int)response.healthyResources).Should().Be(1);
        ((int)response.unhealthyResources).Should().Be(0);
    }

    [Fact]
    public async Task HandleAsync_WithUnhealthyResource_ShouldReturnDegradedStatus()
    {
        // Arrange
        var mockResource = Substitute.For<IMcpResource>();
        mockResource.Uri.Returns("test://resource");
        mockResource.Name.Returns("Test Resource");
        mockResource.Category.Returns("Testing");
        mockResource.GetDescriptor().Returns(new McpResourceDescriptor
        {
            Uri = "",  // Invalid - empty URI
            Name = "Test Resource",
            Category = "Testing",
            IsEnabled = true,
            Version = "1.0"
        });

        _mockRegistry.GetAllResources()
            .Returns(new List<IMcpResource> { mockResource }.AsReadOnly());

        // Act
        var result = await _handler.HandleAsync(null, CancellationToken.None);

        // Assert
        result.Should().NotBeNull();
        var response = result as dynamic;
        ((string)response.status).Should().Be("degraded");
        ((int)response.totalResources).Should().Be(1);
        ((int)response.healthyResources).Should().Be(0);
        ((int)response.unhealthyResources).Should().Be(1);
    }
}
