package coroutine_timer

import (
	"sync"
	"testing"
	"time"

	"goutil/mathUtil"
	"goutil/stringUtil"
)

func init() {
}

func Test_Method1(t *testing.T) {
	imap := make(map[int]struct{})
	var lockObj sync.Mutex

	cb := func(obj interface{}) {
		i := obj.(int)

		lockObj.Lock()
		defer lockObj.Unlock()

		if _, exist := imap[i]; exist == false {
			t.Error(i, "应该删除，不应该回调 Test_Method1")
		}

		delete(imap, i)
	}

	for i := 0; i < 20000; i++ {
		tick := i % 20
		isdel := false
		if tick > 1 {
			isdel = mathUtil.GetRand().GetRandInt(100) < 50
		}
		if isdel == false {
			lockObj.Lock()
			imap[i] = struct{}{}
			lockObj.Unlock()
		}
		id := AddTimer(tick, cb, i)
		if isdel {
			DeleteTimer(id)
		}
	}

	newN := 10000000
	newId := stringUtil.GetNewUUID()

	lockObj.Lock()
	imap[newN] = struct{}{}
	lockObj.Unlock()

	err := AddTimer4(newId, 3, cb, newN)
	if err != nil {
		t.Error(err)
	}

	err = AddTimer4(newId, 3, cb, newN)
	if err == nil {
		t.Error("未检测到重复id")
	}

	for {
		if len(imap) == 0 {
			break
		}

		t.Log("剩余回调次数：", len(imap))
		time.Sleep(time.Second)
	}
}

func Test_Method2(t *testing.T) {
	imap := make(map[int64]struct{})
	var lockObj sync.Mutex

	cb := func(obj interface{}) {
		i := obj.(int64)
		n := time.Now().Unix()
		x := n - i
		//  此处因为启动有暂停5s，所以启动后最近的执行偏差在5s内
		if x > 6 || x < -6 {
			t.Errorf("错误的时间执行了回调函数 tick:%v  now:%v", i, n)
		}

		lockObj.Lock()
		defer lockObj.Unlock()

		if _, exist := imap[i]; exist == false {
			t.Error(i, "应该删除，不应该回调 Test_Method2")
		}

		delete(imap, i)
	}

	for i := 0; i < 20; i++ {
		tick := time.Now().Unix() + int64(i)
		imap[tick] = struct{}{}
		AddTimer3(tick, cb, tick)
	}

	for {
		if len(imap) == 0 {
			break
		}

		t.Log("剩余回调次数：", len(imap))
		time.Sleep(time.Second)
	}

}
