package lib

import "errors"

type GoPool interface {
	Take()
	Return()
	Total() uint32
	Remainder() uint32
}

var _ GoPool = (*myGoPool)(nil)

type myGoPool struct {
	total  uint32        //总数
	poolCh chan struct{} //池子容量
	active bool          //是否激活
}

func NewGoPool(total uint32) (GoPool, error) {
	gp := myGoPool{}
	if !gp.init(total) {
		return nil, errors.New("携程池初始化失败")
	}
	return &gp, nil
}

func (gp *myGoPool) init(total uint32) bool {
	if gp.active {
		return false
	}
	if total == 0 {
		return false
	}

	ch := make(chan struct{}, total)
	n := int(total)
	for i := 0; i < n; i++ {
		ch <- struct{}{}
	}

	gp.poolCh = ch
	gp.total = total
	gp.active = true
	return true
}

func (gp *myGoPool) Take() {
	<-gp.poolCh
}

func (gp *myGoPool) Return() {
	gp.poolCh <- struct{}{}
}

func (gp *myGoPool) Total() uint32 { return gp.total }

func (gp *myGoPool) Remainder() uint32 {
	return uint32(len(gp.poolCh))
}
