using System;

namespace Websocket.Client.Logging
{
	internal class LoggerExecutionWrapper : ILog
	{
		internal LoggerExecutionWrapper(Logger logger, Func<bool> getIsDisabled = null)
		{
			this.WrappedLogger = logger;
			this._callsiteLogger = new LoggerExecutionWrapper.CallSiteExtension();
			Func<bool> func = getIsDisabled;
			if (getIsDisabled == null && (func = LoggerExecutionWrapper.<>c.<>9__4_0) == null)
			{
				func = (LoggerExecutionWrapper.<>c.<>9__4_0 = () => false);
			}
			this._getIsDisabled = func;
		}

		internal Logger WrappedLogger { get; }

		public bool Log(LogLevel logLevel, Func<string> messageFunc, Exception exception = null, params object[] formatParameters)
		{
			if (this._getIsDisabled())
			{
				return false;
			}
			if (messageFunc == null)
			{
				return this.WrappedLogger(logLevel, null, null, LogExtensions.EmptyParams);
			}
			Func<string> func = this._lastExtensionMethod;
			if (func == null || !func.Equals(messageFunc))
			{
				func = null;
				Type declaringType = messageFunc.Method.DeclaringType;
				if (declaringType == typeof(LogExtensions) || (declaringType != null && declaringType.DeclaringType == typeof(LogExtensions)))
				{
					func = messageFunc;
				}
			}
			if (func != null)
			{
				this._lastExtensionMethod = func;
				return this.WrappedLogger(logLevel, LogExtensions.WrapLogSafeInternal(this, messageFunc), exception, formatParameters);
			}
			Func<string> func2 = delegate
			{
				try
				{
					return messageFunc();
				}
				catch (Exception ex)
				{
					this.WrappedLogger(LogLevel.Error, () => "Failed to generate log message", ex, Array.Empty<object>());
				}
				return null;
			};
			return this._callsiteLogger.Log(this.WrappedLogger, logLevel, func2, exception, formatParameters);
		}

		internal const string FailedToGenerateLogMessage = "Failed to generate log message";

		private readonly LoggerExecutionWrapper.Interface2 _callsiteLogger;

		private readonly Func<bool> _getIsDisabled;

		private Func<string> _lastExtensionMethod;

		private interface Interface2
		{
			bool Log(Logger logger, LogLevel logLevel, Func<string> messageFunc, Exception exception, object[] formatParameters);
		}

		private class CallSiteExtension : LoggerExecutionWrapper.Interface2
		{
			bool LoggerExecutionWrapper.Interface2.Log(Logger logger, LogLevel logLevel, Func<string> messageFunc, Exception exception, object[] formatParameters)
			{
				return logger(logLevel, messageFunc, exception, formatParameters);
			}
		}
	}
}
