package sequencetask

import (
	"leafstalk/log"
	"sync"
)

const (
	defaultFunLen = 1000
)

type TaskQueue struct {
	TaskQueueLen int
	allFuns      chan func()
	doneRun      chan struct{}
	wg           sync.WaitGroup
}

func (t *TaskQueue) StartSequenceTaskProcess(taskQueueLen int) {
	t.TaskQueueLen = taskQueueLen
	if t.TaskQueueLen == 0 {
		t.TaskQueueLen = defaultFunLen
	}
	t.allFuns = make(chan func(), t.TaskQueueLen)
	t.wg.Add(1)
	go t.run()
}

func (t *TaskQueue) StopSequenceTaskProcess() {
	close(t.doneRun)
	close(t.allFuns)
	t.wg.Wait()
}

func (t *TaskQueue) AddTask(f func()) bool {
	if len(t.allFuns) >= t.TaskQueueLen {
		return false
	}

	t.allFuns <- f
	return true
}

func (t *TaskQueue) run() {
	defer t.wg.Done()
	t.doneRun = make(chan struct{})
	safeExec := func(f func()) {
		defer func() {
			if err := recover(); err != nil {
				log.Warnln("timercall exec panic:", err)
			}
		}()

		f()
	}

	for {
		select {
		case <-t.doneRun:
			return
		case f, ok := <-t.allFuns:
			if !ok {
				return
			}
			safeExec(f)
		}
	}
}
