package tests

import (
	"testing"

	"github.com/pingcap/dbaas/billing2/config"
	"github.com/pingcap/dbaas/billing2/handler/cachehandler"
	"github.com/pingcap/dbaas/billing2/utils/tests"
	"github.com/shopspring/decimal"
	"github.com/stretchr/testify/suite"
)

type CacheTestSuite struct {
	suite.Suite
}

func TestCacheSuite(t *testing.T) {
	suite.Run(t, new(CacheTestSuite))
}

func (s *CacheTestSuite) TestSetAndGetCache() {
	tests.SetupConfig()
	config.Get().Set(config.EnableCache, true)
	cachehandler.InitWithLocal()
	cache := cachehandler.Get()
	cache.Delete("test_cache", 0, "0")
	test_value := &decimal.Zero
	result := decimal.NewFromInt(1)

	found := cache.Get("test_cache", &result, 0, "0")

	s.False(found)

	cache.Set("test_cache", test_value, 0, "0")
	found = cache.Get("test_cache", &result, 0, "1")
	s.False(found)

	found = cache.Get("test_cache", &result, 0, "0")
	s.True(found)

	s.Zero(result.Cmp(decimal.Zero))

	cache.Delete("test_cache", 0, "0")
	found = cache.Get("test_cache", &result, 0, "0")
	s.False(found)

	var b bool
	s.False(b)

	cache.Set("test_bool", true, "123")
	found = cache.Get("test_bool", &b, "123")
	s.True(found)
	s.True(b)
}

type MyStructC string

type MyStructD struct {
	Value string
}

type MyStructB struct {
	MyStructD
	C MyStructC
}

type MyStructA struct {
	B MyStructB
}

func (s *CacheTestSuite) TestSetAndGetCacheWithStruct() {
	tests.SetupConfig()
	assert := s.Assert()

	config.Get().Set(config.EnableCache, true)
	cachehandler.InitWithLocal()

	obj := MyStructA{
		MyStructB{
			MyStructD: MyStructD{
				Value: "abcd",
			},
			C: MyStructC("aaa"),
		},
	}

	cache := cachehandler.Get()
	cache.Set("test_cache", &obj)

	returnObj := MyStructA{}

	found := cache.Get("test_cache", &returnObj)
	assert.True(found)

	assert.EqualValues(obj.B.C, "aaa")
	assert.EqualValues(obj.B.Value, "abcd")
}
