﻿using System;
using System.Collections.Generic;

namespace QL.LogWriter
{
    [Serializable]
    public class BaseLogWriter : IQuickLogWriter
    {
        private readonly Dictionary<LogType, IQuickLogWriter> _logWriters;

        public BaseLogWriter(Dictionary<LogType, IQuickLogWriter> logWriters)
        {
            _logWriters = logWriters;
        }

        /// <summary>
        /// This extender help programmer to quickly log infromation using the Exception class instance
        /// </summary>
        /// <param name="message">Log message</param>
        /// <param name="objects">Objects that must attach to log</param>
        /// <param name="condition">Detrmine we must capture the log or not</param>
        /// <param name="type">Type of log (Info, Warning, Error, Debug)</param>
        /// <param name="methodName">Method name of cllaser method, automatically filled</param>
        /// <param name="sourceFilePath">Source file path of caller method, automatically filled</param>
        /// <param name="sourceLineNumber">line number of caller, automatically filled</param>
        /// <returns>Determine log successfully stored or not</returns>
        public bool Log(LogType type, string message, object[] objects = null, bool condition = true,

            [System.Runtime.CompilerServices.CallerMemberName] string methodName = "",
            [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
            [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
        {
            try
            {
                bool logWriterFound = false;
                bool registerLogResult = false;

                // If any item was set for All types, we use it's log writer for all type of log operations
                if (_logWriters.ContainsKey(LogType.All))
                {
                    logWriterFound = true;
                    registerLogResult = _logWriters[LogType.All].Log(type, message, objects, condition, methodName,
                        sourceFilePath,
                        sourceLineNumber);
                }

                // Get corresponding log writer of given type and use it for log operation
                foreach (LogType logType in _logWriters.Keys)
                {
                    if (logType.HasFlag(type))
                    {
                        logWriterFound = true;
                        registerLogResult = _logWriters[logType].Log(type, message, objects, condition, methodName,
                            sourceFilePath,
                            sourceLineNumber);
                    }
                }

                // We can't find corresponding log writer for given log type and must fail operation
                if (logWriterFound == false)
                    return false;

                // We found corresponding log writer but the operation fail for some reason and we will log the error in best choice (File log writer is most stable version)
                if (registerLogResult == false)
                    return new FileLogWriter(string.Empty, SplitType.StWeekly).Log(type, message, objects, condition,
                        methodName, sourceFilePath,
                        sourceLineNumber);

                return false;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}