package netstat

import (
	"log"
	"sync"
	"time"

	"wartank/pkg/types"
)

/*
	Сетевая статистика для сетевого соединения
*/

// NetStat -- статистика сетевого соединения
type NetStat struct {
	botNet               types.ИБотСеть
	countByteInterval    int      // Счётчик байтов в текущем интервале
	totalByte            int      // Сколько всего байт передано
	totalMinut           int      // Сколько всего минут работала передача
	countRequestInterval int      // Число запросов
	countErr             int      // Число зафиксированных ошибок
	chTick               chan int // Сигналы времени 1 раз в 5 минут
	block                sync.Mutex
}

// NewNetStat -- возвращает новый *NetStat
func NewNetStat(botNet types.ИБотСеть) *NetStat {
	sf := &NetStat{
		botNet: botNet,
		chTick: make(chan int, 2),
	}
	go sf.run()
	go sf.makeTick()
	return sf
}

// Тикер меток времени 1 раз в 5 минут
func (sf *NetStat) makeTick() {
	defer close(sf.chTick)
	for {
		select {
		case <-sf.botNet.Кнт().Done():
			return
		default:
			time.Sleep(time.Second * 5 * 60)
			sf.chTick <- 1
		}
	}
}

// Главный цикл работы статистики
func (sf *NetStat) run() {
	fnCalc := func() {
		sf.block.Lock()
		defer sf.block.Unlock()
		sf.totalMinut += 5
		mbyte := float32(sf.totalByte) / float32(sf.totalMinut*60) * (3600 * 24 * 30.5) / (1024 * 1024)
		log.Printf("INFO NetStat.run().fnCalc(): запросы=%0.2f/сек\tтраф0=%0.2f бит/сек\tтраф1=%0.2f МБ/мес\tошибки=%v\n",
			float32(sf.countRequestInterval)/300,
			float32(sf.countByteInterval*8)/300,
			mbyte,
			sf.countErr)
		sf.countByteInterval = 0
		sf.countRequestInterval = 0
	}
	for range sf.chTick {
		select {
		case <-sf.botNet.Кнт().Done():
			return
		case <-sf.chTick:
			fnCalc()
		}
	}
}

// IncErr -- добавляет ошибку в статистику
func (sf *NetStat) IncErr() {
	sf.block.Lock()
	defer sf.block.Unlock()
	sf.countErr++
}

// AddByte -- увеличивает счётчик запросов и байтов на передачу/приём
func (sf *NetStat) AddByte(val int) {
	sf.block.Lock()
	defer sf.block.Unlock()
	sf.countByteInterval += val
	sf.totalByte += val
	sf.countRequestInterval++
}
