using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;

namespace Shared
{

    public class LoggingUnitTesting : UnitTesting, IDisposable
    {

        protected ILogger<object> _Logger;
        protected ILoggerFactory _LoggerFactory;
        protected readonly LogLevel? _DefaultLogLevel;
        protected readonly LogLevel? _Log4netProviderLogLevel;
        protected readonly IConfigurationRoot _ConfigurationRoot;
        public ILogger<object> Logger => _Logger;
        public LogLevel? DefaultLogLevel => _DefaultLogLevel;
        public ILoggerFactory LoggerFactory => _LoggerFactory;
        public IConfigurationRoot ConfigurationRoot => _ConfigurationRoot;
        public LogLevel? Log4netProviderLogLevel => _Log4netProviderLogLevel;

        public LoggingUnitTesting(TestContext testContext, Type declaringType) : base(testContext, declaringType)
        {
            _LoggerFactory = new LoggerFactory();
            if (testContext is null || declaringType is null)
            {
                _ConfigurationRoot = null;
                _DefaultLogLevel = null;
                _Log4netProviderLogLevel = null;
            }
            else
            {
                LogLevel logLevel;
                IConfigurationSection configurationSection;
                List<LogLevel> logLevels = new List<LogLevel>();
                string defaultLogLevelSection = "Logging:LogLevel:Default";
                string log4netProviderLogLevelSection = "Logging:LogLevel:Log4netProvider";
                string[] sections = new string[] { defaultLogLevelSection, log4netProviderLogLevelSection };
                IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
                    .AddEnvironmentVariables()
                    .AddJsonFile(_IsEnvironment.AppSettingsFileName, optional: false, reloadOnChange: true);
                _ConfigurationRoot = configurationBuilder.Build();
                foreach (string section in sections)
                {
                    configurationSection = _ConfigurationRoot.GetSection(section);
                    if (configurationSection is null)
                        logLevel = LogLevel.Debug;
                    else if (!Enum.TryParse<LogLevel>(configurationSection.Value, out logLevel))
                        logLevel = LogLevel.Debug;
                    logLevels.Add(logLevel);
                }
                _DefaultLogLevel = logLevels[0];
                _Log4netProviderLogLevel = logLevels[1];
            }
            if (DefaultLogLevel.HasValue)
                _LoggerFactory.AddProvider(new DebugProvider(DefaultLogLevel.Value));
            if (DefaultLogLevel.HasValue)
                _LoggerFactory.AddProvider(new ConsoleProvider(DefaultLogLevel.Value));
            _Logger = _LoggerFactory.CreateLogger<object>();
        }

        public void Dispose()
        {
            _LoggerFactory.Dispose();
        }

    }

}