package storage

import (
	"time"

	"github.com/ngaut/log"
	. "github.com/pingcap/check"
	"github.com/pingcap/schrodinger/pkg/types"
	"github.com/pingcap/schrodinger/util"
)

var _ = Suite(&testTemplateSuite{})

type testTemplateSuite struct {
	store *Storage
}

func (t *testTemplateSuite) SetUpSuite(c *C) {
	t.store = setupStore("testTemplate")
}

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

var testTemplate = &types.TestTemplate{
	Name:    "bank",
	Creator: "cwen",
	Args:    "--db test",
	Status:  types.TestTemplateDone,
	Type:    types.GeneralTest,
	ResourceConfig: types.ResourceRequirements{
		Requests: &types.ResourceRequirement{
			CPU:    "1000m",
			Memory: "2Gi",
		},
		Limits: &types.ResourceRequirement{
			CPU:    "1000m",
			Memory: "2Gi",
		},
	},
	Source: types.TestSource{
		BinaryName: "bank",
		Image:      "127.0.0.1:5001/bank:latest",
		Type:       types.Latest,
		URL:        "http://download.pingcap.com/bank,tar.gz",
	},
	Tags: []string{"ddl", "tidb"},
	Manual: types.Manual{
		Description: "xxx",
		Parameters:  "xxxx",
		Notes:       "xxxxx",
	},
}

var testTemplatePR = &types.TestTemplate{
	Name:    "bank",
	Creator: "cwen",
	Args:    "--db test",
	Status:  types.TestTemplateDone,
	Type:    types.GeneralTest,
	ResourceConfig: types.ResourceRequirements{
		Requests: &types.ResourceRequirement{
			CPU:    "1000m",
			Memory: "2Gi",
		},
		Limits: &types.ResourceRequirement{
			CPU:    "1000m",
			Memory: "2Gi",
		},
	},
	Source: types.TestSource{
		BinaryName: "bank",
		Image:      "127.0.0.1:5001/bank:latest",
		Type:       types.GitSource,
		URL:        "http://download.pingcap.com/bank,tar.gz",
		GitValue: types.GitValue{
			GitType: types.GitTypePr,
			Value:   "110",
		},
	},
	Tags: []string{"tag3"},
	Manual: types.Manual{
		Description: "xxx",
		Parameters:  "xxxx",
		Notes:       "xxxxx",
	},
}

func (t *testTemplateSuite) TestTestTemplate(c *C) {
	ct := &types.TestTemplate{}
	err := util.Clone(ct, testTemplate)
	c.Assert(err, Equals, nil)
	ctPR := &types.TestTemplate{}
	err = util.Clone(ctPR, testTemplatePR)
	c.Assert(err, Equals, nil)

	// test for CreateTestTemplate
	err = t.store.CreateTestTemplate(ct)
	if err != nil {
		log.Error(err)
	}
	c.Assert(err, Equals, nil)

	time.Sleep(2 * time.Second)
	err = t.store.CreateTestTemplate(ctPR)
	if err != nil {
		log.Error(err)
	}
	c.Assert(err, Equals, nil)

	ctLatest, err := t.store.GetTestTemplateByNameAndLatest(ct.Name)
	c.Assert(err, Equals, nil)
	c.Assert(ctLatest, DeepEquals, ct)

	ct1, err := t.store.GetTestTemplateByName(ct.Name)
	c.Assert(err, Equals, nil)
	c.Assert(ct1, DeepEquals, []*types.TestTemplate{ctPR, ct})

	// test for UpdateTestTemplate
	ct.Tags = []string{"ddl", "tikv"}
	ct.Status = types.TestTemplateError
	ct.ResourceConfig.Requests.CPU = "2000m"
	ct.Source.Image = "127.0.0.1:5001/bank:update"
	ct.Manual.Description = "x"

	err = t.store.UpdateTestTemplate(ct)
	if err != nil {
		log.Error(err)
	}
	c.Assert(err, Equals, nil)

	ct2, err := t.store.GetTestTemplate(ct.ID)
	c.Assert(err, Equals, nil)
	c.Assert(ct2, DeepEquals, ct)

	ct2 = &types.TestTemplate{}
	err = util.Clone(ct2, testTemplate)
	c.Assert(err, Equals, nil)

	// test for GetTestTemplatesByTag
	time.Sleep(2 * time.Second)
	ct2.Name = "bank2"
	err = t.store.CreateTestTemplate(ct2)
	if err != nil {
		log.Error(err)
	}
	c.Assert(err, Equals, nil)

	ctsDDL := t.store.GetTestTemplatesByTag("ddl")
	c.Assert(len(ctsDDL), Equals, 2)
	ctsTiDB := t.store.GetTestTemplatesByTag("tidb")
	c.Assert(len(ctsTiDB), Equals, 1)
	ctsEmpty := t.store.GetTestTemplatesByTag("pd")
	c.Assert(len(ctsEmpty), Equals, 0)

	// test for listTestTemplate
	ctsAll := t.store.ListTestTemplate()
	c.Assert(len(ctsAll), Equals, 3)

	// test for delete testTemplate
	t.store.DeleteTestTemplate("bank", ct.ID)
	c.Assert(err, Equals, nil)
	ctsAll = t.store.ListTestTemplate()
	c.Assert(len(ctsAll), Equals, 2)
	c.Assert(ctsAll, DeepEquals, types.TestTemplates{ct2, ctPR})

	t.store.DeleteTestTemplate("bank", ctPR.ID)
	c.Assert(err, Equals, nil)
	ctsAll = t.store.ListTestTemplate()
	c.Assert(len(ctsAll), Equals, 1)
	c.Assert(ctsAll, DeepEquals, types.TestTemplates{ct2})

}
