using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Core;
using log4net.Filter;
using log4net.Layout;
using log4net.Repository;
using System;
using System.IO;
using System.Reflection;

namespace Common
{
    public sealed class Logger
    {
        private const string LOGGER_NAME = "RevitAddin";
        private static readonly Lazy<ILog> InstanceHolder =
            new Lazy<ILog>(InitLog);

        public static ILog Instance => InstanceHolder.Value;

        public static ILog InitLog()
        {
            var appender = new RollingFileAppender
            {
                AppendToFile = true,
                File = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                    $@"ASCON\CadFarmApp\Logs\{LOGGER_NAME}.log")
            };

            PatternLayout layout = new PatternLayout("%date [%thread] %-5level [%logger{1}] %message%newline");
            LevelMatchFilter filter = new LevelMatchFilter();
            filter.LevelToMatch = Level.All;
            filter.ActivateOptions();

            appender.ImmediateFlush = true;
            appender.AppendToFile = true;
            appender.RollingStyle = RollingFileAppender.RollingMode.Size;
            appender.MaxSizeRollBackups = 10;
            appender.DatePattern = "yyyy - MM - dd";
            appender.LockingModel = new FileAppender.MinimalLock();
            appender.ActivateOptions();
            appender.Layout = layout;
            appender.AddFilter(filter);
            appender.Name = "RevitToIfcConverterAppender";

            ILoggerRepository repository = LoggerManager.GetRepository(Assembly.GetCallingAssembly());
            BasicConfigurator.Configure(repository, appender);

            var consoleFilter = new LevelMatchFilter {LevelToMatch = Level.Error, AcceptOnMatch = true};
            consoleFilter.ActivateOptions();
            var consoleAppender = new ConsoleAppender();
            consoleAppender.ActivateOptions();
            consoleAppender.Layout = layout;
            consoleAppender.AddFilter(consoleFilter);
            consoleAppender.AddFilter(new DenyAllFilter());
            BasicConfigurator.Configure(repository, consoleAppender);

            return LogManager.GetLogger(LOGGER_NAME);
        }
    }
}
