using Mesa_Backlog.Library;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using Serilog;
using System.Diagnostics;
using System.Reflection;

namespace Mesa_Backlog.MS_Test;

[TestClass]
public class AB_UnitTestIsEnvironment
{

    private readonly ILogger _Logger;
    private readonly AppSettings _AppSettings;
    private readonly string _WorkingDirectory;
    private readonly IsEnvironment _IsEnvironment;
    private readonly IConfigurationRoot _ConfigurationRoot;

    public AB_UnitTestIsEnvironment()
    {
        ILogger logger;
        AppSettings appSettings;
        string workingDirectory;
        IConfigurationRoot configurationRoot;
        LoggerConfiguration loggerConfiguration = new();
        Assembly assembly = Assembly.GetExecutingAssembly();
        bool debuggerWasAttachedAtLineZero = Debugger.IsAttached || assembly.Location.Contains(@"\bin\Debug");
        IsEnvironment isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
        IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
            .AddEnvironmentVariables()
            .AddJsonFile(isEnvironment.AppSettingsFileName);
        configurationRoot = configurationBuilder.Build();
        appSettings = Library.Binder.AppSettings.Get(configurationRoot);
        workingDirectory = IWorkingDirectory.GetWorkingDirectory(assembly.GetName().Name, appSettings.WorkingDirectoryName);
        Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory);
        _ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, configurationRoot);
        Log.Logger = loggerConfiguration.CreateLogger();
        logger = Log.ForContext<AB_UnitTestIsEnvironment>();
        logger.Information("Complete");
        _Logger = logger;
        _AppSettings = appSettings;
        _IsEnvironment = isEnvironment;
        _WorkingDirectory = workingDirectory;
        _ConfigurationRoot = configurationRoot;
    }

    [TestMethod]
    public void TestMethodNull()
    {
        Assert.IsFalse(_Logger is null);
        Assert.IsFalse(_AppSettings is null);
        Assert.IsFalse(_IsEnvironment is null);
        Assert.IsFalse(_WorkingDirectory is null);
        Assert.IsFalse(_ConfigurationRoot is null);
    }

    [TestMethod]
    public void TestMethodTesta()
    {
        List<string> jsonFiles = new();
        foreach (IConfigurationProvider configurationProvider in _ConfigurationRoot.Providers)
        {
            if (configurationProvider is not JsonConfigurationProvider jsonConfigurationProvider)
                continue;
            jsonFiles.Add(jsonConfigurationProvider.Source.Path);
        }
        Assert.IsTrue(jsonFiles.Any());
        foreach (string jsonFile in jsonFiles)
            _ = new IsEnvironment(jsonFile);
    }

    [TestMethod]
    [TestCategory(nameof(IsEnvironment.Name.WindowsDevelopment))]
    public void TestMethodTestCategory()
    {
        MethodBase? methodBase = new StackFrame().GetMethod();
        Assert.IsNotNull(methodBase);
        TestCategoryAttribute? testCategoryAttribute = methodBase.GetCustomAttribute<TestCategoryAttribute>();
        Assert.IsNotNull(testCategoryAttribute);
        foreach (string testCategory in testCategoryAttribute.TestCategories)
            _ = new IsEnvironment(testCategory);
    }

    [TestMethod]
    public void TestMethodHardcoded()
    {
        _ = new IsEnvironment(isDevelopment: true, isStaging: false, isProduction: false);
        _ = new IsEnvironment(isDevelopment: false, isStaging: true, isProduction: false);
        _ = new IsEnvironment(isDevelopment: false, isStaging: false, isProduction: true);
    }

    [TestMethod]
    public void TestMethodAssembly()
    {
        Assembly assembly = Assembly.GetExecutingAssembly();
        bool debuggerWasAttachedAtLineZero = Debugger.IsAttached || assembly.Location.Contains(@"\bin\Debug");
        IsEnvironment isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
        _ = IsEnvironment.GetEnvironmentName(isEnvironment);
    }

}