package common

import (
	"sync"
	"sync/atomic"
)

type Stopper interface {
	Reset()
	Stop()
	Done() <-chan struct{}
}

var closedchan = make(chan struct{})

func init() {
	close(closedchan)
}

type simpleStopper struct {
	mu   sync.Mutex
	done atomic.Value
}

func (g *simpleStopper) Reset() {
	g.mu.Lock()
	defer g.mu.Unlock()
	g.done = atomic.Value{}
}

func (g *simpleStopper) Stop() {
	g.mu.Lock()
	defer g.mu.Unlock()
	d, _ := g.done.Load().(chan struct{})
	if d == nil {
		g.done.Store(closedchan)
	} else {
		close(d)
	}
}

func (g *simpleStopper) Done() <-chan struct{} {
	d := g.done.Load()
	if d != nil {
		return d.(chan struct{})
	}
	g.mu.Lock()
	defer g.mu.Unlock()
	d = g.done.Load()
	if d == nil {
		d = make(chan struct{})
		g.done.Store(d)
	}
	return d.(chan struct{})
}

// GlobalStopper 全局停止器
var GlobalStopper Stopper = &simpleStopper{}

// GlobalBgStopper 全局后台停止器
var GlobalBgStopper Stopper = &simpleStopper{}
