using System;
using System.Diagnostics;
using System.Threading;
using VCommon.Diagnostics;
using VCommon.Json;

namespace VCommon.Logging
{
    public class VJsonFileLogger : FileLogger
    {
        private readonly bool _includeSourceStackFrameOnly;
        private readonly IVJsonSerializer _jsonSerializer;

        public VJsonFileLogger(IVJsonSerializer jsonSerializer = null,
            int mbSplit = 10, int? preserveDays = null, string logTo = null, bool enableAll = false,
            bool includeSourceStackFrameOnly = true) : base(mbSplit, preserveDays, logTo, enableAll)
        {
            _includeSourceStackFrameOnly = includeSourceStackFrameOnly;
            _jsonSerializer = jsonSerializer ?? VJsonLogSerializer.Instance;
        }

        protected override string FormatMessage(DateTime time, Level level, string summary, object moreInfo)
        {
            var logAt = new StackTrace(true).GetFormattedDetailStackTraceText(typeof(Logger),_includeSourceStackFrameOnly);

            var obj = new { moreInfo, logAt };

            string json;
            try
            {
                json = _jsonSerializer.SerializeObject(obj);
            }
            catch (Exception exception)
            {
                json = _jsonSerializer.SerializeObject(new { LoggerWarn = "json serialize fail", ToString = obj.ToString(), LoggerException = exception, logAt });
            }

            var currentThread = Thread.CurrentThread;

            return $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} {level} {currentThread.Name ?? "Unamed"}({currentThread.ManagedThreadId})"
                   + $"{Environment.NewLine}{summary.Replace("\r", "").Replace("\n", "")}"
                   + $"{Environment.NewLine}{json}"
                   + Environment.NewLine;
        }
    }
}
