// Package controller add by blacknc <blacknc@163.com> at 2023/11/14 10:25:35
package controller

import (
	"context"
	"dataservices/commons/config"
	"dataservices/commons/metrics"
	"dataservices/commons/utils"
	"log"
	"time"

	"github.com/shirou/gopsutil/load"
	"github.com/shirou/gopsutil/mem"
	"github.com/shirou/gopsutil/v3/cpu"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
)

func init() {
	utils.GOWithName("dataservice-execute_systemload", func() {
		d := 5 * time.Second
		tm := time.NewTimer(d)
		ctx := context.TODO()
		for {
			<-tm.C
			cp := cpuPercent() / 100.0
			mp := memPercent() / 100.0
			avg := avgLoad()
			endpointCount := endpointCounterTotal()
			endpointLoad := float64(endpointCount) / 30000.0 // 250QPS * 120s = 30000 Query
			systemLoad := (cp + mp + avg + endpointLoad) / 4
			tilog.Info(ctx, "dataservice-execute_systemload", zap.Float64("system_load", systemLoad),
				zap.Float64("cpu_percent", cp),
				zap.Float64("mem_percent", mp),
				zap.Float64("avg_load", avg),
				zap.Int64("endpoint_count", endpointCount),
				zap.Float64("endpoint_load", endpointLoad),
			)
			metrics.CustomSystemLoad.WithLabelValues(config.RpcEndpointAddr()).Set(systemLoad)
			tm.Reset(d)
		}
	})
}

func cpuPercent() float64 {
	percents, err := cpu.Percent(time.Second, false)
	if err != nil {
		log.Printf("failed to get cpu percent: %v\n", err)
		return 0
	}
	return percents[0]
}

func memPercent() float64 {
	v, err := mem.VirtualMemory()
	if err != nil {
		log.Printf("failed to get virtual memory percent: %v\n", err)
		return 0
	}
	return v.UsedPercent
}

func avgLoad() float64 {
	loadStat, err := load.Avg()
	if err != nil {
		log.Printf("failed to get system average load: %v\n", err)
		return 0
	}
	return loadStat.Load1
}
