package storage

import (
	"reflect"

	"github.com/juju/errors"
	. "github.com/pingcap/check"
	"github.com/pingcap/schrodinger/pkg/types"
)

var _ = Suite(&triggerSuite{})

type triggerSuite struct {
	store *Storage
}

func (t *triggerSuite) SetUpTest(c *C) {
	t.store = setupStore("trigger_job")
}

func (t *triggerSuite) TearDownSuite(c *C) {
	t.store.Close()
}

func (t *triggerSuite) TestSetAndListGithubTriggerInfo(c *C) {
	if err := t.store.SetGithubTriggerInfo(setGithubTriggerInfo); err != nil {
		c.Fatal("creating githubTriggerInfo fails:", errors.ErrorStack(err))
	}

	githubTriggerInfos := t.store.ListGithubTriggerInfo()
	if len(githubTriggerInfos) != 1 {
		c.Fatalf("expect one element, got %v", githubTriggerInfos)
	}
	got := githubTriggerInfos[0]

	if !reflect.DeepEqual(setGithubTriggerInfo, got) {
		c.Fatalf("expect %v, got %v", *setGithubTriggerInfo, *got)
	}

	got, exists := t.store.GetGithubTriggerInfo(setGithubTriggerInfo.JobID)
	c.Assert(exists, Equals, true)
	if !reflect.DeepEqual(setGithubTriggerInfo, got) {
		c.Fatalf("expect %v, got %v", *setGithubTriggerInfo, *got)
	}
	got, exists = t.store.GetGithubTriggerInfo(1234567)
	c.Assert(exists, Equals, false)

	if err := t.store.SetGithubTriggerInfo(updateGithubTriggerInfo); err != nil {
		c.Fatal("updating githubTriggerInfos fails:", errors.ErrorStack(err))
	}

	githubTriggerInfos = t.store.ListGithubTriggerInfo()
	if len(githubTriggerInfos) != 1 {
		c.Fatalf("expect one element, got %v", githubTriggerInfos)
	}
	got = githubTriggerInfos[0]

	if !reflect.DeepEqual(updateGithubTriggerInfo, got) {
		c.Fatalf("expect %v, got %v", *updateGithubTriggerInfo, *got)
	}
}

func (t *triggerSuite) TestSetAndListImmediatelyTriggerInfo(c *C) {
	if err := t.store.SetImmediatelyTriggerInfo(setImmediatelyTriggerInfo); err != nil {
		c.Fatal("creating immediatelyTriggerInfo fails:", errors.ErrorStack(err))
	}

	immediatelyTriggerInfos := t.store.ListImmediatelyTriggerInfo()
	if len(immediatelyTriggerInfos) != 1 {
		c.Fatalf("expect one element, got %v", immediatelyTriggerInfos)
	}
	got := immediatelyTriggerInfos[0]

	if !reflect.DeepEqual(setImmediatelyTriggerInfo, got) {
		c.Fatalf("expect %v, got %v", *setImmediatelyTriggerInfo, *got)
	}

	got, exists := t.store.GetImmediatelyTriggerInfo(setImmediatelyTriggerInfo.JobID)
	c.Assert(exists, Equals, true)

	if !reflect.DeepEqual(setImmediatelyTriggerInfo, got) {
		c.Fatalf("expect %v, got %v", *setImmediatelyTriggerInfo, *got)
	}
	got, exists = t.store.GetImmediatelyTriggerInfo(1234567)
	c.Assert(exists, Equals, false)

	if err := t.store.SetImmediatelyTriggerInfo(updateImmediatelyTriggerInfo); err != nil {
		c.Fatal("updating immediatelyTriggerInfos fails:", errors.ErrorStack(err))
	}

	immediatelyTriggerInfos = t.store.ListImmediatelyTriggerInfo()
	if len(immediatelyTriggerInfos) != 1 {
		c.Fatalf("expect one element, got %v", immediatelyTriggerInfos)
	}
	got = immediatelyTriggerInfos[0]

	if !reflect.DeepEqual(updateImmediatelyTriggerInfo, got) {
		c.Fatalf("expect %v, got %v", *updateImmediatelyTriggerInfo, *got)
	}
}

var setGithubTriggerInfo = &types.GithubTriggerInfo{
	JobID: 1,
	Repo:  "pingcap/tidb",
	Hash:  "0123456",
}

var updateGithubTriggerInfo = &types.GithubTriggerInfo{
	JobID: 1,
	Repo:  "pingcap/tikv",
	Hash:  "654321",
}

var setImmediatelyTriggerInfo = &types.ImmediateTriggerInfo{
	JobID:    1,
	Triggerd: false,
}

var updateImmediatelyTriggerInfo = &types.ImmediateTriggerInfo{
	JobID:    1,
	Triggerd: true,
}
