using XGame.Framework.Utils;
using LitJson;
using System;
using System.Collections.Generic;
using System.IO;

namespace XGame.Framework.Logger
{
    internal class LoggerImpl : ILogger, ILogFlushable, IDisposable
    {
        private ILogColors _colors;
        private WriterRepository _writerRepository;

        private JsonData _jsonData;
        private JsonData jsonData => _jsonData ?? (_jsonData = new JsonData());

        public LoggerImpl(ILogColors logColors, WriterRepository writerRepository)
        {
            _colors = logColors;
            _writerRepository = writerRepository;
        }
        public void Initialize()
        {
            if (_writerRepository != null)
            {
                var logDirectory = LogDefine.LogRootPath;
                if (!Directory.Exists(logDirectory))
                {
                    Directory.CreateDirectory(logDirectory);
                }
            }
        }

        public string Log(LogLevel level, string format, params object[] args)
        {
            var entity = new LogCodeEntity()
            {
                log_level = level.ToString(),
                log_info = format.Format(args),
            };
            if (_writerRepository != null)
            {
                _writerRepository.GetWriter(LogType.Code).Write(entity.ToWriteString());
            }
            var logInfo = entity.ToConsoleString();
            if (_colors != null)
            {
                return _colors.Format(level, logInfo);
            }
            return logInfo;
        }
        public string Event(string type, string id, Dictionary<string, string> infos)
        {
            var entity = new LogEventEntity()
            {
                event_type = type,
                event_id = id,
                info = infos
            };
            if (_writerRepository != null)
            {
                _writerRepository.GetWriter(LogType.Event).Write(entity.ToWriteString(jsonData));
            }
            var logInfo = entity.ToConsoleString();
            if (_colors != null)
            {
                return _colors.Format(LogLevel.Event, logInfo);
            }
            return logInfo;
        }

        public void Dispose()
        {
            (_writerRepository as IDisposable)?.Dispose();
        }

        void ILogFlushable.Flush(LogType logType)
        {
            if (_writerRepository == null)
                return;
            _writerRepository.GetWriter(logType).Flush();
        }
    }
}
