package uid

import (
	"github.com/bwmarrin/snowflake"
	"hash/fnv"
	"math"
	"os"
	"sync"
	"testing"

	"github.com/redis/go-redis/v9"
)

func TestGenerator_GetNumber(t *testing.T) {
	rdb := redis.NewClient(&redis.Options{
		Addr:     "47.97.27.195:6379",
		Password: "lansexiongdi@666",
		DB:       15,
	})

	number, err := NewSignGenerator(rdb).SetWorkerID(1).SetServerID(2).GetNumber()
	if err != nil {
		t.Error(err)
		return
	}

	t.Log(number)
}

func TestGenerator_Num(t *testing.T) {
	rdb := redis.NewClient(&redis.Options{
		Addr:     "47.97.27.195:6379",
		Password: "lansexiongdi@666",
		DB:       15,
	})

	var ids sync.Map
	var wg sync.WaitGroup
	const concurrency = 2000
	wg.Add(concurrency)
	for i := 0; i < concurrency; i++ {
		go func() {
			defer wg.Done()
			id, err := NewSignGenerator(rdb).SetWorkerID(1).SetServerID(2).GetNumber()
			if err != nil {
				t.Error(err)
				return
			}
			if _, exists := ids.LoadOrStore(id, true); exists {
				t.Errorf("duplicate ID generated, id:%d", id)
			}
		}()
	}
	wg.Wait()
}

func TestSignGenerator_ReverseNumber(t *testing.T) {
	reverseNumber := NewSignGenerator(nil).ReverseNumber(556081583078248449)
	t.Log(reverseNumber)
}

func Test_GenerateNo(t *testing.T) {
	//uid := uuid.New().String()
	//t.Log(len(uid))
	//t.Log(uid)

	serverIdStr, _ := os.Hostname()
	t.Log(serverIdStr)

	id := hashMod(serverIdStr)
	t.Log(id)

	node, err := snowflake.NewNode(int64(id))
	if err != nil {
		t.Error(err)
		return
	}

	nid := node.Generate().String()

	t.Log(nid)
	t.Log(len(nid))
}

func hashMod(hashStr string) int {
	hash := fnv.New32a()
	_, _ = hash.Write([]byte(hashStr))

	hashValue := hash.Sum32()
	return int(math.Mod(float64(hashValue), 32))
}

func TestGenerateID(t *testing.T) {
	nodeID := int64(1) // 确保唯一
	node, _ := snowflake.NewNode(nodeID)
	var ids sync.Map
	var wg sync.WaitGroup
	const concurrency = 2000
	wg.Add(concurrency)
	for i := 0; i < concurrency; i++ {
		go func() {
			defer wg.Done()
			id := node.Generate().String()
			if _, exists := ids.LoadOrStore(id, true); exists {
				t.Errorf("duplicate ID generated, id:%s", id)
			}
		}()
	}
	wg.Wait()
}
