package store_test

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"source.quilibrium.com/quilibrium/monorepo/node/store"
)

func TestIter(t *testing.T) {
	db := store.NewInMemKVDB()
	db.Set([]byte{0x01}, []byte{0x01})
	db.Set([]byte{0x02}, []byte{0x02})
	db.Set([]byte{0x03}, []byte{0x03})
	db.Set([]byte{0x04}, []byte{0x04})
	db.Set([]byte{0x06}, []byte{0x06})
	db.Set([]byte{0x07}, []byte{0x07})
	db.Set([]byte{0x08}, []byte{0x08})
	db.Set([]byte{0x010}, []byte{0x010})
	db.Set([]byte{0x012}, []byte{0x012})
	db.Set([]byte{0x014}, []byte{0x014})
	iter, err := db.NewIter([]byte{0x01}, []byte{0x04})
	assert.NoError(t, err)
	assert.True(t, iter.First())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x01})
	assert.ElementsMatch(t, iter.Key(), []byte{0x01})
	assert.True(t, iter.Next())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x02})
	assert.ElementsMatch(t, iter.Key(), []byte{0x02})
	assert.True(t, iter.Next())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x03})
	assert.ElementsMatch(t, iter.Key(), []byte{0x03})
	assert.True(t, iter.Next())
	assert.False(t, iter.Valid())
	assert.NoError(t, iter.Close())

	iter, err = db.NewIter([]byte{0x06}, []byte{0x09})
	assert.NoError(t, err)
	assert.True(t, iter.First())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x06})
	assert.ElementsMatch(t, iter.Key(), []byte{0x06})
	assert.True(t, iter.Next())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x07})
	assert.ElementsMatch(t, iter.Key(), []byte{0x07})
	assert.True(t, iter.Next())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x08})
	assert.ElementsMatch(t, iter.Key(), []byte{0x08})
	assert.True(t, iter.Next())
	assert.False(t, iter.Valid())

	iter, err = db.NewIter([]byte{0x05}, []byte{0x09})
	assert.NoError(t, err)
	assert.True(t, iter.First())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x06})
	assert.ElementsMatch(t, iter.Key(), []byte{0x06})
	assert.True(t, iter.Next())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x07})
	assert.ElementsMatch(t, iter.Key(), []byte{0x07})
	assert.True(t, iter.Next())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x08})
	assert.ElementsMatch(t, iter.Key(), []byte{0x08})
	assert.True(t, iter.Next())
	assert.False(t, iter.Valid())

	iter, err = db.NewIter([]byte{0x010}, []byte{0x015})
	assert.NoError(t, err)
	assert.True(t, iter.First())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x10})
	assert.ElementsMatch(t, iter.Key(), []byte{0x10})
	assert.True(t, iter.Next())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x12})
	assert.ElementsMatch(t, iter.Key(), []byte{0x12})
	assert.True(t, iter.Next())
	assert.True(t, iter.Valid())
	assert.ElementsMatch(t, iter.Value(), []byte{0x14})
	assert.ElementsMatch(t, iter.Key(), []byte{0x14})
	assert.True(t, iter.Next())
	assert.False(t, iter.Valid())
}
