using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Threading;

namespace HealthMonitor.WebApi.DbLog
{
	public class EfCoreLogger : ILogger
	{
		private readonly string _categoryName;

		//protected static ConcurrentStack<string> ScopeStack { get; } = new ConcurrentStack<string>();

		public EfCoreLogger(string categoryName)
		{
			_categoryName = categoryName;
		}

        public IDisposable? BeginScope<TState>(TState state) where TState : notnull
        {
            return new NoopDisposable();
        }

		//public IDisposable BeginScope<TState>(TState state)
		//{
		//	//ScopeStack.Push(state.ToString());
		//	return new NoopDisposable();
		//}

		public bool IsEnabled(LogLevel logLevel)
		{
			return logLevel >= EfCoreLogProvider.LogThisAndAbout;
		}

		public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception, string> formatter)
		{
			switch (logLevel)
			{
				case LogLevel.Trace:
				case LogLevel.Debug:
					{
						var content = formatter(state, exception!).Replace(Path.DirectorySeparatorChar, '\t');
						Serilog.Log.Debug(content);
					}
					break;

				case LogLevel.Information:
					{
						var content = formatter(state, exception!).Replace(Path.DirectorySeparatorChar, '\t');
						Serilog.Log.Information(content);
					}
					break;

				case LogLevel.Warning:
					{
						var content = formatter(state, exception!).Replace(Path.DirectorySeparatorChar, '\t');
						Serilog.Log.Warning(content);
					}
					break;

				case LogLevel.Error:
					Serilog.Log.Error(formatter(state, exception!));
					break;

				case LogLevel.Critical:
					Serilog.Log.Fatal(formatter(state, exception!));
					break;
			}
		}

		private class NoopDisposable : IDisposable
		{
			public void Dispose()
			{
				//while (!ScopeStack.TryPop(out _))
				//{
				//	Thread.Sleep(100);
				//}
			}
		}
	}
}