package common

import (
	"fmt"
	"math/rand"
	"os"
	"testing"

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

func TestLimitKeyspaces(t *testing.T) {
	t.Parallel()

	records := KeyspaceRecords{
		{KeyspaceId: 3, KeyspaceStateChangedAt: 300},
		{KeyspaceId: 1, KeyspaceStateChangedAt: 100},
		{KeyspaceId: 2, KeyspaceStateChangedAt: 200},
		{KeyspaceId: 4, KeyspaceStateChangedAt: 100},
	}

	require.Equal(t, records, LimitKeyspaces(records, 0))
	require.Equal(t, records, LimitKeyspaces(records, -1))
	require.Equal(t, records, LimitKeyspaces(records, 10))

	limited := LimitKeyspaces(records, 2)
	require.Len(t, limited, 2)
	require.Equal(t, uint32(1), limited[0].KeyspaceId)
	require.Equal(t, uint32(4), limited[1].KeyspaceId)
}

func TestKeyspaceRecords(t *testing.T) {
	var records0 KeyspaceRecords
	for i := 0; i < 10; i++ {
		record := &KeyspaceRecord{}
		record.KeyspaceId = uint32(i) * 10
		record.KeyspaceName = fmt.Sprintf("keyspace-name-%d", i)
		record.KeyspaceCreatedAt = rand.Int63()
		record.KeyspaceStateChangedAt = rand.Int63()

		records0 = append(records0, record)
	}

	// write records from records0 to file
	f, err := os.OpenFile("./test_keyspace_records.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
	require.NoError(t, err)

	err = records0.WriteTo(f)
	require.NoError(t, err)
	err = f.Close()
	require.NoError(t, err)

	// update keyspace
	f, err = os.OpenFile("./test_keyspace_records.txt", os.O_RDWR, 0666)
	require.NoError(t, err)

	recordsMap, err := CacheArchiveKeyspaceRecords(f)
	require.NoError(t, err)

	for _, record := range recordsMap {
		record.ArchivedEtcdPath = true
		record.ArchivedPdRule = true
		record.ArchivedKeyspace = true
		record.ArchivedRegionLabel = true
	}

	err = UpdateArchiveKeyspaceRecords(recordsMap, f)
	require.NoError(t, err)
	err = f.Close()
	require.NoError(t, err)

	// read records from file to records1
	f, err = os.OpenFile("./test_keyspace_records.txt", os.O_RDONLY, 0666)
	require.NoError(t, err)

	var records1 KeyspaceRecords
	err = records1.ReadFrom(f)
	require.NoError(t, err)
	err = f.Close()
	require.NoError(t, err)

	for _, record := range records0 {
		record.ArchivedEtcdPath = true
		record.ArchivedPdRule = true
		record.ArchivedKeyspace = true
		record.ArchivedRegionLabel = true
	}
	require.Equal(t, records0, records1)

	// remove file
	err = os.Remove("./test_keyspace_records.txt")
	require.NoError(t, err)
}
