package trigger

import (
	"leafstalk/log"
	"time"
)

type RoutineTrigger struct {
	chNotify chan struct{}
	doneRun  chan struct{}
}

// 启动协程，手动触发协程函数的执行
func (r *RoutineTrigger) StrartRoutine(f func()) {
	r.chNotify = make(chan struct{}, 1)
	r.doneRun = make(chan struct{})

	safeExec := func(f func()) {
		defer func() {
			if err := recover(); err != nil {
				log.Warnln("timercall exec panic:", err)
			}
		}()

		f()
	}

	go func() {
		for {
			select {
			case <-r.chNotify:
				safeExec(f)
			case <-r.doneRun:
				return
			}
		}
	}()
}

// 启动协程，手动触发协程函数的执行， 并且也会定时自动执行协程函数
func (r *RoutineTrigger) StrartTimerRoutine(f func(), d time.Duration) {

	r.chNotify = make(chan struct{}, 1)
	r.doneRun = make(chan struct{})
	ticker := time.NewTicker(d)

	safeExec := func(f func()) {
		defer func() {
			if err := recover(); err != nil {
				log.Warnln("timercall exec panic:", err)
			}
		}()

		f()
	}

	go func() {
		for {
			select {
			case <-r.chNotify:
				safeExec(f)
			case <-r.doneRun:
				ticker.Stop()
				return
			case <-ticker.C:
				safeExec(f)
			}
		}
	}()
}

func (r *RoutineTrigger) Trigger() {
	select {
	case r.chNotify <- struct{}{}:
	default:
	}
}

func (r *RoutineTrigger) Stop() {
	close(r.doneRun)
}
