using adas_core.Application.Repositories.Interfaces;
using adas_core.Domain.Models.MongoModels;
using Microsoft.Extensions.Logging;
using MongoDB.Bson;
using Moq;
using ServiceConfigService = adas_core.Application.Services.ServiceConfigService;

namespace adas_core.Test.Services;

[TestFixture]
public class ServiceConfigServiceTest
{
    /// <summary>
    /// Initializes the test environment by creating mock instances of the service configuration repository and logger, and instantiating the <see cref="ServiceConfigService"/> under test.
    /// </summary>
    [SetUp]
        public void Setup()
        {
            _serviceConfigRepositoryMock = new Mock<IServiceConfigRepository>();
    
            _logger = new Mock<ILogger<ServiceConfigService>>();
    
            _serviceConfigService = new ServiceConfigService(
                _serviceConfigRepositoryMock.Object,
                _logger.Object
            );
        }

    private ServiceConfigService _serviceConfigService;

    private Mock<IServiceConfigRepository> _serviceConfigRepositoryMock;
    private Mock<ILogger<ServiceConfigService>> _logger;

    private static ObjectId _id = ObjectId.GenerateNewId();

    /// <summary>
    /// Verifies that the <see cref="ServiceConfig"/> service returns a <see cref="ServiceConfig"/> instance
    /// when retrieving an existing configuration by its string identifier.
    /// </summary>
    [Test]
        public async Task Get_Find_Id_Return_ServiceConfig()
        {
            var serviceConfig = new ServiceConfig
            {
                StrId = _id.ToString()
            };
    
            _serviceConfigRepositoryMock.Setup(s => s.FindById(_id.ToString())).ReturnsAsync(serviceConfig);
    
            var result = await _serviceConfigService.Get(serviceConfig.StrId);
    
            Assert.That(result, Is.Not.Null);
        }

    /// <summary>
    /// Verifies that the Get method returns a <see cref="ServiceConfig"/> when the specified id is not found by the repository's <c>FindById</c>, falling back to a lookup with any <see cref="ObjectId"/>.
    /// </summary>
    [Test]
        public async Task Get_Not_Find_Id_Return_ServiceConfig()
        {
            var serviceConfig = new ServiceConfig
            {
                StrId = _id.ToString()
            };
    
            _serviceConfigRepositoryMock.Setup(s => s.FindById(_id)).ReturnsAsync((ServiceConfig?)null);
            _serviceConfigRepositoryMock.Setup(s => s.FindById(It.IsAny<ObjectId>())).ReturnsAsync(serviceConfig);
    
            var result = await _serviceConfigService.Get(_id.ToString());
    
            Assert.That(result, Is.Not.Null);
        }
}