package cachev2_test

import (
	"encoding/json"
	"testing"

	cache "github.com/fiskerinc/cloud-services/pkg/cachev2"
	"github.com/fiskerinc/cloud-services/pkg/db/queries"
	"github.com/fiskerinc/cloud-services/pkg/db/queries/mocks"
	"github.com/fiskerinc/cloud-services/pkg/redis/tester"
	redis "github.com/fiskerinc/cloud-services/pkg/redisv2"
	"github.com/fiskerinc/cloud-services/pkg/testhelper"
)

var mockRedis redis.Client
var mockDB queries.CarsInterface

func setupRedisMock() {
	redis.MockRedisConnection()
}

func setupDBMock() {
	mockDB = &mocks.MockCars{}
}

type mockRedisCache struct {
	redis.Connection
}

func (c *mockRedisCache) GetSet(id string, data interface{}) error {
	drivers := []string{"valid-id-1", "valid-id-2", "valid-id-3"}

	dataBytes, err := json.Marshal(drivers)
	if err != nil {
		return err
	}

	err = json.Unmarshal(dataBytes, data)
	if err != nil {
		return err
	}

	return nil
}

type mockRedisEmptyCache struct {
	redis.Connection
}

func (c *mockRedisEmptyCache) GetSet(id string, data interface{}) error {
	drivers := []string{}

	dataBytes, err := json.Marshal(drivers)
	if err != nil {
		return err
	}

	err = json.Unmarshal(dataBytes, data)
	if err != nil {
		return err
	}

	return nil
}

func (c *mockRedisEmptyCache) SetObjects(id []string, data []interface{}, expire int) error {
	return nil
}

func TestRetrieveAndCacheDriverIDs(t *testing.T) {
	setupRedisMock()
	setupDBMock()
	mockRedis = &mockRedisCache{}
	redisPool := tester.NewMockClientPool(mockRedis)
	drivers := cache.NewDriversCache(redisPool, mockDB)

	_, err := drivers.RetrieveDriverIDs("FISKER123")
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "TestRetrieveAndCacheDriverIDs", "no error", err)
	}

	mockRedis = &mockRedisEmptyCache{}
	_, err = drivers.RetrieveDriverIDs("FISKER456")
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "TestRetrieveAndCacheDriverIDs", "no error", err)
	}
}

func TestRetrieveAndCacheDriverIDsAsSet(t *testing.T) {
	setupRedisMock()
	setupDBMock()
	mockRedis = &mockRedisCache{}
	redisPool := tester.NewMockClientPool(mockRedis)

	drivers := cache.NewDriversCache(redisPool, mockDB)

	_, err := drivers.RetrieveDriverIDs("FISKER123")
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "TestRetrieveAndCacheDriverIDs", "no error", err)
	}

	mockRedis = &mockRedisEmptyCache{}
	_, err = drivers.RetrieveDriverIDsAsSet("FISKER456")
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "TestRetrieveAndCacheDriverIDs", "no error", err)
	}
}
