#  Copyright 2020 Modelling, Simulation and Design Lab (MSDL) at
#  McGill University and the University of Antwerp (http://msdl.cs.mcgill.ca/)
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

"""Helper file for :mod:`pypdevsbbl.generic.queues`.

This file contains common queueing disciplines and the element that
will be enqueued in the :class:`pypdevsbbl.generic.queues.SimpleQueue` and
:class:`pypdevsbbl.generic.queues.Queue` building blocks.
"""

FIFO = lambda time, val, ix: -ix
"""First-In-First-Out kind of queue. This is the most commonly used one.

Note:
	Keep in mind that we use a maxheap in our queue.
"""

FCFS = FIFO
"""Alias for :meth:`FIFO`."""

LIFO = lambda time, val, ix: ix
"""Last-In-First-Out kind of queue. This is used for stacks etc.

Note:
	Keep in mind that we use a maxheap in our queue.
"""

class QueueElement:
	"""Simple Queue Element for storing all necessary information and doing valid comparisons.

	Creates a special kind of tuple for enqueueing items, allowing for sorting on priorities
	and remembering their arrival times (which is used for reneging).

	Warning:
		This is not a DEVS building block.

	Args:
		priority (comparable):	The priority of the item in the queue.
		item (any):				The item to enqueue.
		arrival_time (numeric):	(Absolute) time of arrival of the item.

	Attributes:
		priority (comparable):	The priority of the item in the queue.
		item (any):				The item to enqueue.
		arrival_time (numeric):	(Absolute) time of arrival of the item.
	"""

	def __init__(self, priority, item, arrival_time):
		self.priority = priority
		self.item = item
		self.arrival_time = arrival_time

	def __lt__(self, other):
		return self.priority < other.priority

	def __gt__(self, other):
		return self.priority > other.priority

	def __le__(self, other):
		return self.priority <= other.priority

	def __ge__(self, other):
		return self.priority >= other.priority

	def __repr__(self):
		return "QueueElement<%i, %s>" % (self.priority, repr(self.item))
