using System;
using System.Collections.Generic;

namespace QC.QSPR.Collections;

public class CircularByteQueue
{
	private Queue<byte> queue = new Queue<byte>();

	private int queueSize;

	public CircularByteQueue(int queueSize)
	{
		if (queueSize <= 0)
		{
			throw new Exception("CircularByteQueue(): Queue Size Is <= Zero");
		}
		this.queueSize = queueSize;
	}

	public bool EnqueueByte(byte data)
	{
		bool result = true;
		lock (queue)
		{
			if (queue.Count == queueSize)
			{
				queue.Dequeue();
				result = false;
			}
			queue.Enqueue(data);
			return result;
		}
	}

	public bool EnqueueBytes(ref byte[] data, int count)
	{
		if (count > queueSize)
		{
			throw new Exception("EnqueueBytes(): Count > Queue Size");
		}
		bool result = true;
		lock (queue)
		{
			for (int i = 0; i < count; i++)
			{
				if (queue.Count == queueSize)
				{
					queue.Dequeue();
					result = false;
				}
				queue.Enqueue(data[i]);
			}
			return result;
		}
	}

	public bool DequeueByte(ref byte data)
	{
		lock (queue)
		{
			if (queue.Count == 0)
			{
				return false;
			}
			data = queue.Dequeue();
		}
		return true;
	}

	public int DequeueBytes(ref byte[] data, int maxCount)
	{
		lock (queue)
		{
			for (int i = 0; i < maxCount; i++)
			{
				if (queue.Count == 0)
				{
					return i;
				}
				data[i] = queue.Dequeue();
			}
			return maxCount;
		}
	}

	public int GetCount()
	{
		lock (queue)
		{
			return queue.Count;
		}
	}
}
