using System.Diagnostics;
using Autofac;
using Microsoft.ApplicationInsights;
using Microsoft.Extensions.Logging;
using PlanTempus.Components.ModuleRegistry;
using PlanTempus.Core.Configurations;
using PlanTempus.Core.Configurations.JsonConfigProvider;
using PlanTempus.Core.ModuleRegistry;
using PlanTempus.Core.SeqLogging;
using PlanTempus.Database.ModuleRegistry;
using CrypticWizard.RandomWordGenerator;

namespace PlanTempus.X.TDD;

/// <summary>
///     Act as base class for tests. Avoids duplication of test setup code
/// </summary>
[TestClass]
public abstract class TestFixture
{
    private readonly string _configurationFilePath;

    protected TestFixture() : this(null)
    {
    }
    public string GetRandomWord()
    {
        var myWordGenerator = new WordGenerator();
        return myWordGenerator.GetWord(WordGenerator.PartOfSpeech.verb);
    }
    public TestFixture(string configurationFilePath)
    {
        if (configurationFilePath is not null)
            _configurationFilePath = configurationFilePath?.TrimEnd('/') + "/";

        CreateContainerBuilder();
        Container = ContainerBuilder.Build();
    }

    protected IContainer Container { get; private set; }
    protected ContainerBuilder ContainerBuilder { get; private set; }

    public virtual IConfigurationRoot Configuration()
    {
        var configuration = new ConfigurationBuilder()
            .AddJsonFile($"{_configurationFilePath}appconfiguration.dev.json")
            .Build();

        return configuration;
    }

    protected virtual void CreateContainerBuilder()
    {
        var configuration = Configuration();
        var builder = new ContainerBuilder();

        builder.RegisterGeneric(typeof(Logger<>))
            .As(typeof(ILogger<>))
            .SingleInstance();


        builder.RegisterModule(new DbPostgreSqlModule
        {
            ConnectionString = configuration.GetConnectionString("DefaultConnection")
        });

        builder.RegisterModule(new TelemetryModule
        {
            TelemetryConfig = configuration.GetSection("ApplicationInsights").ToObject<TelemetryConfig>()
        });
        builder.RegisterModule(new SeqLoggingModule
        {
            SeqConfiguration = configuration.GetSection("SeqConfiguration").ToObject<SeqConfiguration>()
        });

        builder.RegisterModule<CommandModule>();
        builder.RegisterModule<SecurityModule>();
        
        ContainerBuilder = builder;
    }

    [TestCleanup]
    public void CleanUp()
    {
        Trace.Flush();
        var telemetryClient = Container.Resolve<TelemetryClient>();
        telemetryClient.Flush();

        if (Container is null) return;

        Container.Dispose();
        Container = null;
    }
}