package priority

import (
	"sync"
)

// 全局导出变量：所有导入 pro 包的代码均可直接使用 pro.Registry
var RegistryTask = NewTaskRegistry()

// TaskRegistry：线程安全的任务注册表，仅保存 Running==true 的任务
type TaskRegistry struct {
	mu sync.RWMutex
	m  map[string]TaskInfo // key: task name (e.g., "PA", "C2C", "DTMF")
}

// NewTaskRegistry 创建新注册表
func NewTaskRegistry() *TaskRegistry {
	return &TaskRegistry{
		m: make(map[string]TaskInfo),
	}
}

// Register 启动并注册一个任务（仅当 Running == true 时才存入）
func (r *TaskRegistry) Register(name string, t TaskInfo) {
	if !t.Running {
		return // 不注册未运行的任务
	}
	r.mu.Lock()
	defer r.mu.Unlock()
	r.m[name] = t
}

// StopAndUnregister 标记任务为停止，并立即从注册表中删除（推荐在任务结束时调用）
func (r *TaskRegistry) StopAndUnregister(name string) {
	r.mu.Lock()
	defer r.mu.Unlock()
	delete(r.m, name)
}

// UpdateStatus 更新任务状态；若设为 false，则自动删除（满足你“任务结束即删除”的需求）
func (r *TaskRegistry) UpdateStatus(name string, newStatus bool) {
	r.mu.Lock()
	defer r.mu.Unlock()

	if !newStatus {
		delete(r.m, name) // 自动清理：Running=false → 移除
		return
	}

	// 若 newStatus == true，尝试更新或插入（需原 task info 完整）
	if t, ok := r.m[name]; ok {
		t.Running = true
		r.m[name] = t
	} else {
		// 如果没有旧记录，但你要“重新启用”，需外部提供完整 TaskInfo → 建议用 Register()
	}
}

// Get 获取指定任务（nil if not found or not running）
func (r *TaskRegistry) Get(name string) (TaskInfo, bool) {
	r.mu.RLock()
	defer r.mu.RUnlock()
	t, ok := r.m[name]
	return t, ok && t.Running
}

// ListAll 返回所有当前运行中的任务副本（安全遍历）
func (r *TaskRegistry) ListAll() []TaskInfo {
	r.mu.RLock()
	defer r.mu.RUnlock()
	list := make([]TaskInfo, 0, len(r.m))
	for _, t := range r.m {
		if t.Running { // 冗余检查，确保一致性
			list = append(list, t)
		}
	}
	return list
}

// HighestPriorityRunningTask returns the task with smallest Priority value,
// which means highest scheduling priority (e.g., Priority=0 > 1 > 10).
// Returns (key, task, found). If no task exists, found is false.
func (r *TaskRegistry) HighestPriorityRunningTask() (string, TaskInfo, bool) {

	r.mu.RLock()
	defer r.mu.RUnlock()

	var bestKey string
	var best TaskInfo
	found := false

	for key, task := range r.m {
		if !found || task.Priority < best.Priority {
			bestKey = key
			best = task
			found = true
		}
	}
	return bestKey, best, found
}

// HighestPriorityRunningTask1 returns the task with smallest Priority value except C2C,
// which means highest scheduling priority (e.g., Priority=0 > 1 > 10).
// Returns (key, task, found). If no task exists, found is false.
func (r *TaskRegistry) HighestPriorityRunningTask1() (string, TaskInfo, bool) {

	r.mu.RLock()
	defer r.mu.RUnlock()

	var bestKey string
	var best TaskInfo
	found := false

	for key, task := range r.m {
		if task.RunType == "C2C" {
			continue
		}

		if !found || task.Priority < best.Priority {
			bestKey = key
			best = task
			found = true
		}
	}

	//lfshook.NewLogger().Infof("====HighestPriorityRunningTask1 ret=====%s", best.RunType)
	return bestKey, best, found
}
