using System;
using System.Collections.Generic;
using System.Threading;

namespace QC.QMSLPhone;

public static class Logger
{
	private static bool enabled;

	private static int maxMessageSize;

	private static int maxQueueCount;

	private static ManualResetEvent messagesAvailable;

	private static Queue<Message> q;

	private static bool[] messageTypeEnableMap;

	private static uint sequenceNumber;

	private static object sequenceNumberLock;

	public static bool Enabled
	{
		get
		{
			return enabled;
		}
		set
		{
			enabled = value;
		}
	}

	public static int MaxMessageSize
	{
		get
		{
			return maxMessageSize;
		}
		set
		{
			if (value < 0)
			{
				throw new ArgumentOutOfRangeException("MaxMessageSize");
			}
			maxMessageSize = value;
		}
	}

	public static int MaxQueueCount
	{
		get
		{
			return maxQueueCount;
		}
		set
		{
			if (value < 0)
			{
				throw new ArgumentOutOfRangeException("MaxQueueCount");
			}
			lock (q)
			{
				maxQueueCount = value;
				if (maxQueueCount > 0)
				{
					while (q.Count > maxQueueCount)
					{
						q.Dequeue();
					}
				}
			}
		}
	}

	public static ManualResetEvent MessagesAvailable => messagesAvailable;

	static Logger()
	{
		enabled = false;
		maxMessageSize = 256;
		maxQueueCount = 0;
		messagesAvailable = new ManualResetEvent(initialState: false);
		q = new Queue<Message>();
		sequenceNumber = 0u;
		sequenceNumberLock = new object();
		MessageType[] array = (MessageType[])Enum.GetValues(typeof(MessageType));
		messageTypeEnableMap = new bool[array.GetLength(0)];
		int num = 0;
		MessageType[] array2 = array;
		for (int i = 0; i < array2.Length; i++)
		{
			_ = array2[i];
			messageTypeEnableMap[num] = false;
			num++;
		}
	}

	public static void Clear()
	{
		lock (q)
		{
			q.Clear();
			messagesAvailable.Reset();
		}
	}

	public static List<Message> GetAllMessages()
	{
		List<Message> list = new List<Message>();
		lock (q)
		{
			while (q.Count > 0)
			{
				list.Add(q.Dequeue());
			}
			if (q.Count == 0)
			{
				messagesAvailable.Reset();
			}
		}
		return list;
	}

	public static List<Message> GetUpToNMessages(uint n)
	{
		uint num = 0u;
		List<Message> list = new List<Message>();
		lock (q)
		{
			while (q.Count > 0 && num < n)
			{
				list.Add(q.Dequeue());
				num++;
			}
			if (q.Count == 0)
			{
				messagesAvailable.Reset();
			}
		}
		return list;
	}

	public static void EnableMessageType(MessageType messageType)
	{
		messageTypeEnableMap[(int)messageType] = true;
	}

	public static void DisableMessageType(MessageType messageType)
	{
		messageTypeEnableMap[(int)messageType] = false;
	}

	public static bool IsMessageTypeEnabled(MessageType messageType)
	{
		return messageTypeEnableMap[(int)messageType];
	}

	public static void Add(Message message)
	{
		if (!enabled || !messageTypeEnableMap[(int)message.type])
		{
			return;
		}
		lock (q)
		{
			message.sequenceNumber = sequenceNumber;
			if (sequenceNumber == uint.MaxValue)
			{
				sequenceNumber = 0u;
			}
			else
			{
				sequenceNumber++;
			}
			if (q.Count < maxQueueCount || maxQueueCount == 0)
			{
				q.Enqueue(message);
			}
			messagesAvailable.Set();
		}
	}
}
