using System;
using System.Collections.Generic;
using EonaCat.Logger.EonaCatCoreLogger;
using EonaCat.Logger.EonaCatCoreLogger.Models;
using EonaCat.Logger.GrayLog;
using EonaCat.Logger.Syslog;

namespace EonaCat.Logger.Managers
{
    // This file is part of the EonaCat project(s) which is released under the Apache License.
    // See the LICENSE file or go to https://EonaCat.com/License for full license details.

    /// <summary>
    /// Logger settings.
    /// </summary>
    public class LoggerSettings
    {
        public event LogDelegate OnLog;
        public delegate void LogDelegate(EonaCatLogMessage message);

        /// <summary>
        /// Determines if we need to use the local time in the logging or UTC (default:false)
        /// </summary>
        public bool UseLocalTime { get; set; }

        public string Id { get; set; } = "EonaCatLogger";

        /// <summary>
        /// Determines if we need to remove the prefix [EonaCatLogger] from each message (default: false)
        /// </summary>
        public bool RemoveMessagePrefix { get; set; }


        /// <summary>
        /// Header format.  Provide a string that specifies how the preamble of each message should be structured.  You can use variables including:
        /// {ts}: UTC timestamp
        /// {host}: Hostname
        /// {thread}: Thread ID
        /// {sev}: Severity
        /// Default: {ts} {host} {thread} {sev}
        /// A space will be inserted between the header and the message.
        /// </summary>
        public string HeaderFormat
        {
            get
            {
                return _headerFormat;
            }
            set
            {
                if (string.IsNullOrEmpty(value)) _headerFormat = "";
                else _headerFormat = value;
            }
        }

        /// <summary>
        /// Timestamp format.
        /// </summary>
        public string TimestampFormat
        {
            get
            {
                return _timestampFormat;
            }
            set
            {
                if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(HeaderFormat));
                _timestampFormat = value;
            }
        }

        /// <summary>
        /// Enable or disable console logging.  
        /// Settings this to true will first validate if a console exists. 
        /// If a console is not available, it will be set to false.
        /// </summary>
        public bool EnableConsole
        {
            get
            {
                return _enableConsole;
            }
            set
            {
                if (value) _enableConsole = ConsoleExists();
                else _enableConsole = false;
            }
        }

        /// <summary>
        /// Enable or disable use of color for console messages.
        /// </summary>
        public bool EnableColors { get; set; } = true;

        /// <summary>
        /// Colors to use for console messages based on message severity.
        /// </summary>
        public ColorSchema Colors
        {
            get
            {
                return _colors;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException(nameof(Colors));
                }
                _colors = value;
            }
        }

        public ELogType MaxLogType { get; set; } = ELogType.TRACE;

        public bool SendToSyslogServers { get; set; }

        public List<SyslogServer> SysLogServers { get; set; }

        public bool SendToSplunkServers { get; set; }

        public bool SendToGrayLogServers { get; set; }

        public List<SplunkServer.SplunkServer> SplunkServers { get; set; }

        public List<GrayLogServer> GrayLogServers { get; set; }

        /// <summary>
        /// Determines if the fileLogging is enabled
        /// </summary>
        public bool EnableFileLogging { get; set; } = true;

        private FileLoggerOptions _fileLoggerOptions;

        /// <summary>
        /// FileLogger settings.
        /// </summary>
        public FileLoggerOptions FileLoggerOptions
        {
            get
            {
                if (_fileLoggerOptions == null)
                {
                    _fileLoggerOptions = CreateDefaultFileLoggerOptions();
                }
                return _fileLoggerOptions;
            }

            set
            {
                _fileLoggerOptions = value;
            }
        }

        private static FileLoggerOptions CreateDefaultFileLoggerOptions()
        {
            return new FileLoggerOptions();
        }

        /// <summary>
        /// Set the origin of where the OnLog event was initiated
        /// </summary>
        public string LogOrigin { get; set; }

        private string _headerFormat = "{ts} {host} {thread} {sev}";
        private string _timestampFormat = "yyyy-MM-dd HH:mm:ss";
        private bool _enableConsole = true;
        private int _maxMessageLength = 1024;
        private ColorSchema _colors = new ColorSchema();
       

        private static bool ConsoleExists()
        {
            try
            {
                bool test1 = Environment.UserInteractive;
                bool test2 = Console.WindowHeight > 0;
                return test1 && test2;
            }
            catch (Exception)
            {
                return false;
            }
        }

        internal void OnLogEvent(EonaCatLogMessage eonaCatLogMessage)
        {
            OnLog?.Invoke(eonaCatLogMessage);
        }

        internal void ResetLogEvent()
        {
            OnLog = null;
        }
    }
}