package goroutineMgr

import (
	"fmt"
	"runtime"
	"sync"

	"framework/monitorNewMgr"
	"goutil/logUtil"
)

var (
	goroutineInfoMap   map[string]int = make(map[string]int)
	goroutineInfoMutex sync.RWMutex
	goroutineWarnCount int = 50
)

func init() {
	monitorNewMgr.RegisterMonitorFunc(monitor)
}

// 设置系统协程上报阈值
func SetGoroutineWarnCount(warnCount int) {
	goroutineWarnCount = warnCount
}

func registerGoroutineInfo(goroutineName string, count int) {
	goroutineInfoMutex.Lock()
	defer goroutineInfoMutex.Unlock()

	goroutineInfoMap[goroutineName] = count
}

// 监控指定的goroutine
func Monitor(goroutineName string) {
	increaseCount(goroutineName)
	registerGoroutineInfo(goroutineName, 1)
}

// 只添加数量，不监控
func MonitorZero(goroutineName string) {
	increaseCount(goroutineName)
}

// 释放监控
func ReleaseMonitor(goroutineName string) {
	if r := recover(); r != nil {
		logUtil.LogUnknownError(r)
	}

	decreaseCount(goroutineName)
}

func monitor() error {
	// 判断当前goroutine数量是否达到打印条件（数量查过设置的值就打印）
	if goroutineWarnCount >= runtime.NumGoroutine() {
		return nil
	}
	/*
		先记录活跃的goroutine的数量信息
		然后再判断数量是否匹配
	*/
	logGoroutineCountInfo()

	goroutineInfoMutex.RLock()
	defer goroutineInfoMutex.RUnlock()

	for goroutineName, expectedCount := range goroutineInfoMap {
		if currCount := getGoroutineCount(goroutineName); currCount != expectedCount {
			return fmt.Errorf("%s需要%d个goroutine，现在有%d个", goroutineName, expectedCount, currCount)
		}
	}

	return nil
}
