package datastructures

import "errors"

// Queue a First in First out data structure.
type Queue struct {
	elements []any
}

// Enqueue adds and element to the queue
func (q *Queue) Enqueue(el any) {
	q.elements = append(q.elements, el)
}

// Dequeue removes an element from the queue
func (q *Queue) Dequeue() (any, error) {
	if q.IsEmpty() {
		return nil, errors.New("empty queue")
	}
	el := q.elements[0]
	q.elements = q.elements[1:]
	return el, nil
}

// Peek retrieves a copy of the next element in the queue.
func (q *Queue) Peek() (any, error) {
	if q.IsEmpty() {
		return nil, errors.New("empty queue")
	}
	return q.elements[0], nil
}

// IsEmpty checks if the queue has any elements
func (q *Queue) IsEmpty() bool {
	return q.Size() == 0
}

// Size checks the size of the queue
func (q *Queue) Size() int {
	return len(q.elements)
}