// Package controller add by blacknc <blacknc@163.com> at 2023/11/13 17:53:54
package controller

import (
	"sync/atomic"
	"time"
)

var endpointCounter *Counter

func init() {
	endpointCounter = NewCounter(120)
}

func endpointCounterAdd(value int64) int64 {
	return endpointCounter.Add(time.Now().Unix(), value)
}
func endpointCounterTotal() int64 {
	return endpointCounter.Count(time.Now().Unix())
}

func NewCounter(maxLength int64) *Counter {
	return &Counter{
		maxLength: maxLength,
		capacity:  maxLength * 2,
		counter:   make([]atomic.Int64, maxLength*2),
	}
}

type Counter struct {
	maxLength int64
	capacity  int64
	counter   []atomic.Int64
	lastKey   atomic.Int64
}

func (c *Counter) Add(key, value int64) int64 {
	c.lastKey.Store(key)
	idx := key % c.capacity
	return c.counter[idx].Add(value)
}

func (c *Counter) Count(key int64) int64 {
	lastKey := c.lastKey.Load()
	length := c.maxLength - (key - lastKey)
	var sum int64
	idx := int(lastKey % c.capacity)
	for i := 0; i < int(length); i++ {
		sum += c.counter[idx].Load()
		idx--
		if idx < 0 {
			idx = int(c.capacity) - 1
		}
	}
	return sum
}
