package util

import (
	"os"
	"runtime/debug"
	"sync"
	"time"

	"github.com/bytedance/gopkg/util/gopool"
	"github.com/go-kratos/kratos/v2/log"
)

var (
	logger *log.Helper
	once   sync.Once
)

// getLogger 懒加载获取日志器
func getLogger() *log.Helper {
	once.Do(func() {
		// 如果没有手动初始化，使用默认的标准输出日志器
		if logger == nil {
			stdLogger := log.With(log.NewStdLogger(os.Stdout),
				"ts", log.DefaultTimestamp,
				"caller", log.DefaultCaller,
				"component", "safe_pool",
			)
			logger = log.NewHelper(stdLogger)
		}
	})
	return logger
}

// InitSafePool 初始化安全协程池（可选，如果不调用会使用默认日志器）
func InitSafePool(l log.Logger) {
	logger = log.NewHelper(l)
}

// SafeGo 安全执行协程
// taskName: 协程任务名称，用于日志记录
// fn: 要执行的函数
func SafeGo(taskName string, fn func()) {
	gopool.Go(func() {
		defer func() {
			if r := recover(); r != nil {
				stack := debug.Stack()
				getLogger().Errorf("协程 [%s] 发生panic: %v\n堆栈信息:\n%s", taskName, r, string(stack))
			}
		}()

		// 记录协程开始执行
		getLogger().Infof("协程 [%s] 开始执行", taskName)
		start := time.Now()

		// 执行用户函数
		fn()

		// 记录协程执行完成
		duration := time.Since(start)
		getLogger().Infof("协程 [%s] 执行完成，耗时: %v", taskName, duration)
	})
}
