package id_generator

import (
	"math/rand"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

const maxMachineID = uint16(1<<10 - 1)

func TestGetLocalIPs(t *testing.T) {
	ipAddrs, err := getLocalIPs()
	assert.NoError(t, err)
	assert.NotEmpty(t, ipAddrs)
	t.Log("get ip addresses:", ipAddrs)
}

func TestGetValidSnowflakeMachineID(t *testing.T) {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 100; i++ {
		rawBytes := make([]byte, r.Intn(64))
		r.Read(rawBytes)
		mid := mustGetValidSnowflakeMachineID(rawBytes)
		assert.GreaterOrEqual(t, mid, uint16(0))
		assert.LessOrEqual(t, mid, maxMachineID)
	}
}

func TestHostSnowflakeMachineIDGenerator(t *testing.T) {
	machineIDGenerator := NewHostSnowflakeMachineIDGenerator()
	mid := machineIDGenerator.MustGenerateMachineID()
	assert.GreaterOrEqual(t, mid, uint16(0))
	assert.LessOrEqual(t, mid, maxMachineID)

	for i := 0; i < 10; i++ {
		assert.Equal(t, mid, machineIDGenerator.MustGenerateMachineID())
	}
}

func TestSnowflakeIDGenerator(t *testing.T) {
	idGenerator := MustNewSnowflakeIDGenerator(NewHostSnowflakeMachineIDGenerator())
	idSet := make(map[uint64]struct{}, 128)
	testNum := 100
	for i := 0; i < testNum; i++ {
		id := idGenerator.NextID()
		idSet[id] = struct{}{}
	}
	assert.Equal(t, testNum, len(idSet))
}
