// 不要使用 准备删除
// 使用 TaskFuncDispatcher
package coroutine

import (
	"fmt"
	"leafstalk/log"
	"sync"
	"time"
)

// Worker represents a worker that executes tasks.
type Worker struct {
	ID        int
	TaskQueue chan func()
	QuitChan  chan bool
}

// NewWorker creates a new worker.
func NewWorker(id int, taskQueue chan func(), quitChan chan bool) *Worker {
	return &Worker{
		ID:        id,
		TaskQueue: taskQueue,
		QuitChan:  quitChan,
	}
}

// Start starts the worker.
func (w *Worker) Start(wg *sync.WaitGroup) {
	wg.Add(1)
	go func() {
		defer wg.Done()
		for {
			select {
			case task := <-w.TaskQueue:
				func() {
					if err := recover(); err != nil {
						log.Warnln("TaskList Worker Start panic:", err)
					}

					task()
				}()
			case <-w.QuitChan:
				log.Warnf("TaskList Worker %d quitting", w.ID)
				return
			}
		}
	}()
}

// TaskList represents a list of tasks.
type TaskList struct {
	Tasks    chan func()
	Workers  []*Worker
	wg       sync.WaitGroup
	QuitChan chan bool
}

// NewTaskList creates a new task list.
func NewTaskList(numWorkers, bufferSize int) *TaskList {
	taskChannel := make(chan func(), bufferSize)
	quitChan := make(chan bool)

	tl := &TaskList{
		Tasks:    taskChannel,
		Workers:  make([]*Worker, 0),
		QuitChan: quitChan,
	}

	// Start workers
	for i := 0; i < numWorkers; i++ {
		worker := NewWorker(i+1, taskChannel, quitChan)
		tl.Workers = append(tl.Workers, worker)
		worker.Start(&tl.wg)
	}

	return tl
}

// AddTask adds a task to the task list.
func (tl *TaskList) AddTask(task func()) {
	tl.Tasks <- task
}

// Stop stops the task list.
func (tl *TaskList) Stop() {
	close(tl.Tasks)
	close(tl.QuitChan)
	tl.wg.Wait()
}

func testTaskList() {
	numWorkers := 3
	bufferSize := 10
	taskList := NewTaskList(numWorkers, bufferSize)

	// Add tasks to the task list
	taskList.AddTask(func() {
		fmt.Println("1")
	})

	// Wait for tasks to complete
	time.Sleep(6 * time.Second)

	// Stop task list
	taskList.Stop()
}
