package door

import "log"

// A First-In-First-Out buffer using generics.
type FIFOBuffer[T any] struct {
	data  []T
	index int
}

/*
Construct new buffer.

buffer := NewFIFOBuffer[rune](5)

This would construct a buffer that will hold
rune type, with a buffer size of 5.
*/
func NewFIFOBuffer[T any](maxsize int) FIFOBuffer[T] {
	return FIFOBuffer[T]{data: make([]T, maxsize)}
}

// Is buffer empty?
func (f *FIFOBuffer[T]) Empty() bool {
	return f.index == 0
}

// Push item into buffer.
func (f *FIFOBuffer[T]) Push(value T) {
	if f.index >= len(f.data) {
		log.Panicf("Exceeded FIFOBuffer index %d size %d %#v", f.index, len(f.data), f.data)
	}
	f.data[f.index] = value
	f.index++
}

// Pop element from buffer.
func (f *FIFOBuffer[T]) Pop() T {
	if f.index == 0 {
		log.Panicf("Pop from empty FIFOBuffer (size %d).", len(f.data))
	}
	f.index--
	return f.data[f.index]
}