package chat

import "sync"

// History contains the history entries
type History struct {
	entries []interface{}
	head    int
	size    int
	sync.RWMutex
}

// NewHistory constructs a new history of the given size
func NewHistory(size int) *History {
	return &History{
		entries: make([]interface{}, size),
	}
}

// Add adds the given entry to the entries in the history
func (h *History) Add(entry interface{}) {
	h.Lock()
	defer h.Unlock()

	max := cap(h.entries)
	h.head = (h.head + 1) % max
	h.entries[h.head] = entry
	if h.size < max {
		h.size++
	}
}

// Len returns the number of entries in the history
func (h *History) Len() int {
	return h.size
}

// Get recent entries
func (h *History) Get(num int) []interface{} {
	h.RLock()
	defer h.RUnlock()

	max := cap(h.entries)
	if num > h.size {
		num = h.size
	}

	r := make([]interface{}, num)
	for i := 0; i < num; i++ {
		idx := (h.head - i) % max
		if idx < 0 {
			idx += max
		}
		r[num-i-1] = h.entries[idx]
	}

	return r
}