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.Services;

public class ResourceDiscoveryServiceTests
{
    private readonly IResourceDiscoveryService _discoveryService;
    private readonly ILogger<ResourceDiscoveryService> _mockLogger;

    public ResourceDiscoveryServiceTests()
    {
        _mockLogger = Substitute.For<ILogger<ResourceDiscoveryService>>();
        _discoveryService = new ResourceDiscoveryService(_mockLogger);
    }

    [Fact]
    public void DiscoverResourceTypes_ShouldFindAllResourceImplementations()
    {
        // Act
        var resourceTypes = _discoveryService.DiscoverResourceTypes();

        // Assert
        resourceTypes.Should().NotBeEmpty();
        resourceTypes.Should().AllSatisfy(type =>
        {
            typeof(IMcpResource).IsAssignableFrom(type).Should().BeTrue();
            type.IsInterface.Should().BeFalse();
            type.IsAbstract.Should().BeFalse();
        });
    }

    [Fact]
    public void DiscoverResourceTypes_ShouldFindKnownResources()
    {
        // Act
        var resourceTypes = _discoveryService.DiscoverResourceTypes();

        // Assert - should find at least these known resources
        var typeNames = resourceTypes.Select(t => t.Name).ToList();
        typeNames.Should().Contain("ProjectsListResource");
        typeNames.Should().Contain("ProjectsGetResource");
        typeNames.Should().Contain("IssuesSearchResource");
        typeNames.Should().Contain("IssuesGetResource");
        typeNames.Should().Contain("SprintsCurrentResource");
        typeNames.Should().Contain("UsersListResource");
    }

    [Fact]
    public void DiscoverResourceTypes_ShouldNotIncludeInterfaces()
    {
        // Act
        var resourceTypes = _discoveryService.DiscoverResourceTypes();

        // Assert
        resourceTypes.Should().NotContain(t => t.IsInterface);
    }

    [Fact]
    public void DiscoverResourceTypes_ShouldNotIncludeAbstractClasses()
    {
        // Act
        var resourceTypes = _discoveryService.DiscoverResourceTypes();

        // Assert
        resourceTypes.Should().NotContain(t => t.IsAbstract);
    }
}
