// Package traffic 统计经过本进程的 HTTP 流量（请求体 + 响应体），供后台评估带宽。
// 说明：前有 Nginx 时边缘出口可能更大；WebSocket 升级后部分流量可能不经此计数。
package traffic

import (
	"sync"
	"sync/atomic"
	"time"
)

var (
	totalIn  atomic.Uint64
	totalOut atomic.Uint64
	started  = time.Now()

	tickerOnce sync.Once

	mu          sync.Mutex
	secIn       [60]uint64
	secOut      [60]uint64
	lastSnapIn  uint64
	lastSnapOut uint64
	tickIndex   int64
)

func ensureTicker() {
	tickerOnce.Do(func() {
		go func() {
			t := time.NewTicker(time.Second)
			defer t.Stop()
			for range t.C {
				tick()
			}
		}()
	})
}

func tick() {
	ti := totalIn.Load()
	to := totalOut.Load()
	mu.Lock()
	i := int(tickIndex % 60)
	secIn[i] = ti - lastSnapIn
	secOut[i] = to - lastSnapOut
	lastSnapIn = ti
	lastSnapOut = to
	tickIndex++
	mu.Unlock()
}

// AddIn 记录请求体已读字节。
func AddIn(n int) {
	if n > 0 {
		ensureTicker()
		totalIn.Add(uint64(n))
	}
}

// AddOut 记录响应已写字节。
func AddOut(n int) {
	if n > 0 {
		ensureTicker()
		totalOut.Add(uint64(n))
	}
}

// Snapshot 返回当前统计（近 60 秒为滚动窗口内各秒增量之和）。
func Snapshot() map[string]any {
	ensureTicker()
	tin := totalIn.Load()
	tout := totalOut.Load()
	up := time.Since(started).Seconds()

	mu.Lock()
	var sumIn, sumOut uint64
	for i := 0; i < 60; i++ {
		sumIn += secIn[i]
		sumOut += secOut[i]
	}
	mu.Unlock()

	var avgDown, avgUp, recentDown, recentUp float64
	if up > 0.5 {
		avgDown = float64(tout) * 8 / (up * 1e6) // Mbps 出站（自启动平均）
		avgUp = float64(tin) * 8 / (up * 1e6)   // Mbps 入站
	}
	recentDown = float64(sumOut) * 8 / (60 * 1e6)
	recentUp = float64(sumIn) * 8 / (60 * 1e6)

	return map[string]any{
		"bytes_in_total":       tin,
		"bytes_out_total":      tout,
		"bytes_in_last_60s":    sumIn,
		"bytes_out_last_60s":   sumOut,
		"uptime_seconds":       up,
		"avg_egress_mbps":      round2(avgDown),
		"avg_ingress_mbps":     round2(avgUp),
		"recent_egress_mbps":   round2(recentDown),
		"recent_ingress_mbps":  round2(recentUp),
	}
}

func round2(x float64) float64 {
	if x < 0 {
		return 0
	}
	return float64(int64(x*100+0.5)) / 100
}
