package storage

import (
	"time"

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

var _ = Suite(&buildTaskSuite{})

type buildTaskSuite struct {
	store *Storage
}

func (b *buildTaskSuite) SetUpTest(c *C) {
	b.store = setupStore("build_task")
}

func (b *buildTaskSuite) TearDownSuite(c *C) {
	b.store.Close()
}

var insertBuildTask = &types.BuildTask{
	Status: types.TaskPending,
	Information: types.Infomation{
		Repo:      "github.com/pingcap/tidb",
		Branch:    "master",
		Platform:  "centos7",
		BinaryURL: "xxxx",
		Force:     false,
		Fuse:      false,
	},
}

var updateBuildTask = &types.BuildTask{
	Status: types.TaskRunning,
	Ftime:  time.Now().Format(util.TimeFormat),
	Information: types.Infomation{
		Repo:      "github.com/pingcap/pd",
		Branch:    "testing",
		Platform:  "centos7",
		BinaryURL: "xxx",
		Force:     false,
		Fuse:      true,
	},
}

func (b *buildTaskSuite) TestCreateBuildTask(c *C) {
	err := b.store.CreateBuildTask(insertBuildTask)
	c.Assert(err, Equals, nil)

	tasks, err := b.store.ListBuildTask(BuildTaskConditions{
		Status: []types.TaskStatus{types.TaskPending},
	})

	c.Assert(err, Equals, nil)
	c.Assert(len(tasks), Equals, 1)
	c.Assert(tasks[0], DeepEquals, insertBuildTask)
}

func (b *buildTaskSuite) TestUpdateBuildTask(c *C) {
	b.TestCreateBuildTask(c)

	updateBuildTask.ID = insertBuildTask.ID
	updateBuildTask.Ctime = insertBuildTask.Ctime

	err := b.store.UpdateBuildTask(updateBuildTask)
	c.Assert(err, Equals, nil)

	tasks, err := b.store.ListBuildTask(BuildTaskConditions{
		Status: []types.TaskStatus{types.TaskRunning},
	})

	c.Assert(err, Equals, nil)
	c.Assert(len(tasks), Equals, 1)
	c.Assert(tasks[0], DeepEquals, updateBuildTask)
}

func (b *buildTaskSuite) TestGetBuildTaskByID(c *C) {
	b.TestCreateBuildTask(c)

	newTask, ok := b.store.GetBuildTaskByID(insertBuildTask.ID)
	c.Assert(ok, Equals, true)
	c.Assert(newTask, DeepEquals, insertBuildTask)
}

func (b *buildTaskSuite) TestListBuildTask(c *C) {
	b.TestCreateBuildTask(c)

	tasks, err := b.store.ListBuildTask(BuildTaskConditions{
		Status: []types.TaskStatus{types.TaskPending},
	})

	c.Assert(err, Equals, nil)
	c.Assert(len(tasks), Equals, 1)
	c.Assert(tasks[0], DeepEquals, insertBuildTask)

	tasks, err = b.store.ListBuildTask(BuildTaskConditions{
		Status: []types.TaskStatus{types.TaskRunning},
	})

	c.Assert(err, Equals, nil)
	c.Assert(len(tasks), Equals, 0)

	updateBuildTask.Ctime = insertBuildTask.Ctime
	err = b.store.CreateBuildTask(updateBuildTask)
	c.Assert(err, Equals, nil)

	tasks, err = b.store.ListBuildTask(BuildTaskConditions{
		Status: []types.TaskStatus{types.TaskRunning},
	})
	c.Assert(err, Equals, nil)
	c.Assert(len(tasks), Equals, 1)

	tasks, err = b.store.ListBuildTask(BuildTaskConditions{
		Status: []types.TaskStatus{types.TaskPending, types.TaskRunning},
	})
	c.Assert(err, Equals, nil)
	c.Assert(len(tasks), Equals, 2)

	tasks, err = b.store.ListBuildTask(BuildTaskConditions{
		Status: []types.TaskStatus{types.TaskPending, types.TaskRunning},
		Limit:  1,
	})
	c.Assert(err, Equals, nil)
	c.Assert(len(tasks), Equals, 1)
}
