package mock_store

import (
	"os"
	"testing"

	"git.p78su.freemyip.com/svi/gostore/pkg/mock/mock_service"
)

type tester struct {
	t     *testing.T
	serv  *mock_service.MockService
	store *MockStore
}

func TestMockStore(t *testing.T) {
	fnClear := func() {
		_ = os.RemoveAll("./store")
	}
	fnClear()
	defer fnClear()
	sf := &tester{
		t: t,
	}
	sf.create()
	sf.put()
	sf.get()
	sf.find()
	sf.del()
}

// Удаление ключа
func (sf *tester) del() {
	sf.t.Log("del")
	sf.delBad1()
	sf.delGood1()
}

func (sf *tester) delGood1() {
	sf.t.Log("delGood1")
	err := sf.store.Del("key")
	if err != nil {
		sf.t.Fatalf("delGood1(): err=\n\t%v", err)
	}
}

// Испорчена переменная IsBad_
func (sf *tester) delBad1() {
	sf.t.Log("delBad1")
	IsBad_ = true
	err := sf.store.Del("key")
	if err == nil {
		sf.t.Fatalf("delBad1(): err==nil")
	}
	IsBad_ = false
}

// Поиск ключей по префиксу
func (sf *tester) find() {
	sf.t.Log("find")
	sf.findBad1()
	sf.findGood1()
}

func (sf *tester) findGood1() {
	sf.t.Log("findGood1")
	lstKey, err := sf.store.Find("key")
	if err != nil {
		sf.t.Fatalf("findGood1(): err=\n\t%v", err)
	}
	if lstKey == nil {
		sf.t.Fatalf("findGood1(): lstKey==nil")
	}
}

// Испорчена переменная IsBad_
func (sf *tester) findBad1() {
	sf.t.Log("findBad1")
	IsBad_ = true
	_, err := sf.store.Find("key")
	if err == nil {
		sf.t.Fatalf("findBad1(): err==nil")
	}
	IsBad_ = false
}

// Проверка получения ключа из хранилища
func (sf *tester) get() {
	sf.t.Log("get")
	sf.getBad1()
	sf.getBad2()
	sf.getGood1()
}

func (sf *tester) getGood1() {
	sf.t.Log("getGood1")
	binData, err := sf.store.Get("key")
	if err != nil {
		sf.t.Fatalf("getGood1(): err=\n\t%v", err)
	}
	if binData == nil {
		sf.t.Fatalf("getGood1(): binData==nil")
	}
	binData1, err := sf.store.Get("key1")
	if err == nil {
		sf.t.Fatalf("getGood1(): err==nil")
	}
	if binData1 != nil {
		sf.t.Fatalf("getGood1(): binData1!=nil")
	}

}

// Нет ключа для получения
func (sf *tester) getBad2() {
	sf.t.Log("getBad2")
	binData, err := sf.store.Get("")
	if err == nil {
		sf.t.Fatalf("getBad2(): err==nil")
	}
	if binData != nil {
		sf.t.Fatalf("getBad2(): binData!=nil")
	}
}

// Испорчена переменная IsBad_
func (sf *tester) getBad1() {
	sf.t.Log("getBad1")
	IsBad_ = true
	binData, err := sf.store.Get("key")
	if err == nil {
		sf.t.Fatalf("getBad1(): err==nil")
	}
	if binData != nil {
		sf.t.Fatalf("getBad1(): binData!=nil")
	}
	IsBad_ = false
}

// Помещение ключа в мок-хранилище
func (sf *tester) put() {
	sf.t.Log("put")
	sf.putBad1()
	sf.putBad2()
	sf.putGood1()
}

func (sf *tester) putGood1() {
	sf.t.Log("putGood1")
	err := sf.store.Put("key", []byte{})
	if err != nil {
		sf.t.Fatalf("putGood1(): err=\n\t%v", err)
	}
}

// Нет ключа для помещения в хранилище
func (sf *tester) putBad2() {
	sf.t.Log("putBad2")
	err := sf.store.Put("", nil)
	if err == nil {
		sf.t.Fatalf("putBad2(): err==nil")
	}
}

// Испорчена переменная IsBad_
func (sf *tester) putBad1() {
	sf.t.Log("putBad1")
	IsBad_ = true
	err := sf.store.Put("key", []byte{})
	if err == nil {
		sf.t.Fatalf("putBad1(): err==nil")
	}
	IsBad_ = false
}

// Создание мок-хранилища
func (sf *tester) create() {
	sf.t.Log("create")
	sf.createBad1()
	sf.createBad2()
	sf.createGood1()
}

func (sf *tester) createGood1() {
	sf.t.Log("createGood1")
	var err error
	sf.store, err = NewMockStore(sf.serv)
	if err != nil {
		sf.t.Fatalf("createGood1(): err=\n\t%v", err)
	}
	if sf.store == nil {
		sf.t.Fatalf("createGood1(): store==nil")
	}
}

// Нет объекта сервиса
func (sf *tester) createBad2() {
	sf.t.Log("createBad2")
	store, err := NewMockStore(nil)
	if err == nil {
		sf.t.Fatalf("createBad2(): err==nil")
	}
	if store != nil {
		sf.t.Fatalf("createBad2(): store!=nil")
	}
}

// Испорчена переменная IsBad_
func (sf *tester) createBad1() {
	sf.t.Log("createBad1")
	sf.serv = mock_service.NewMockService()
	IsBad_ = true
	store, err := NewMockStore(sf.serv)
	if err == nil {
		sf.t.Fatalf("createBad1(): err==nil")
	}
	if store != nil {
		sf.t.Fatalf("createBad1(): store!=nil")
	}
	IsBad_ = false
}
