package engine

// MetricsRingBuffer — кольцевой буфер истории метрик для одной ноды.
// Хранит до `capacity` последних снапшотов NodeState.
// Потокобезопасен: используется внутри Engine (защищён engine.mu).
type MetricsRingBuffer struct {
	buf      []NodeSnapshot
	capacity int
	head     int // позиция следующей записи
	size     int // текущее количество элементов
}

// NodeSnapshot — снапшот метрик на момент времени.
type NodeSnapshot struct {
	ActiveCalls     int
	MaxCalls        int
	IdleCPU         float64
	LoadAvg         float64
	CallFailureRate float64
	Score           float64
	TS              int64
}

// newMetricsRingBuffer создаёт кольцевой буфер заданной ёмкости.
func newMetricsRingBuffer(capacity int) *MetricsRingBuffer {
	return &MetricsRingBuffer{
		buf:      make([]NodeSnapshot, capacity),
		capacity: capacity,
	}
}

// push добавляет снапшот в буфер. Если буфер заполнен, затирает самый старый.
func (b *MetricsRingBuffer) push(snapshot NodeSnapshot) {
	b.buf[b.head] = snapshot
	b.head = (b.head + 1) % b.capacity
	if b.size < b.capacity {
		b.size++
	}
}

// snapshot возвращает копию всех снапшотов в хронологическом порядке.
func (b *MetricsRingBuffer) snapshot() []NodeSnapshot {
	result := make([]NodeSnapshot, b.size)
	start := b.head - b.size
	if start < 0 {
		start += b.capacity
	}
	for i := 0; i < b.size; i++ {
		result[i] = b.buf[(start+i)%b.capacity]
	}
	return result
}
