package scheduling

import (
	"fmt"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"go.skia.org/infra/go/deepequal/assertdeep"
	"go.skia.org/infra/go/testutils/unittest"
	"go.skia.org/infra/task_scheduler/go/specs"
	"go.skia.org/infra/task_scheduler/go/types"
)

func fullTaskCandidate() *taskCandidate {
	return &taskCandidate{
		Attempt:            3,
		BuildbucketBuildId: 8888,
		Commits:            []string{"a", "b"},
		Diagnostics:        &taskCandidateDiagnostics{},
		CasInput:           "lonely-parameter",
		CasDigests:         []string{"browns"},
		CasUsesIsolate:     true,
		Jobs: []*types.Job{{
			Id: "dummy",
		}},
		ParentTaskIds:  []string{"38", "39", "40"},
		RetryOf:        "41",
		Score:          99,
		StealingFromId: "rich",
		TaskKey: types.TaskKey{
			RepoState: types.RepoState{
				Repo:     "nou.git",
				Revision: "1",
			},
			Name: "Build",
		},
		TaskSpec: &specs.TaskSpec{
			Isolate: "confine",
		},
	}
}

func TestCopyTaskCandidate(t *testing.T) {
	unittest.SmallTest(t)
	v := fullTaskCandidate()
	cp := v.CopyNoDiagnostics()
	require.Nil(t, cp.Diagnostics)
	cp.Diagnostics = &taskCandidateDiagnostics{}
	assertdeep.Copy(t, v, cp)
}

func TestTaskCandidateJSON(t *testing.T) {
	unittest.SmallTest(t)
	v := fullTaskCandidate()
	assertdeep.JSONRoundTripEqual(t, v)
}

func TestTaskCandidateId(t *testing.T) {
	unittest.SmallTest(t)
	t1 := makeTaskCandidate("task1", []string{"k:v"})
	t1.Repo = "Myrepo"
	t1.Revision = "abc123"
	t1.ForcedJobId = "someID"
	id1 := t1.MakeId()
	k1, err := parseId(id1)
	require.NoError(t, err)
	require.Equal(t, t1.TaskKey, k1)

	// ForcedJobId is allowed to be empty.
	t1.ForcedJobId = ""
	id1 = t1.MakeId()
	k1, err = parseId(id1)
	require.NoError(t, err)
	require.Equal(t, t1.TaskKey, k1)

	// Test a try job.
	t1.Server = "https://my-patch.com"
	t1.Issue = "10101"
	t1.Patchset = "42"
	id1 = t1.MakeId()
	k1, err = parseId(id1)
	require.NoError(t, err)
	require.Equal(t, t1.TaskKey, k1)

	badIds := []string{
		"",
		"taskCandidate|a",
		"taskCandidate|a|b||ab",
		"20160831T000018.497703717Z_000000000000015b",
	}
	for _, id := range badIds {
		_, err := parseId(id)
		require.Error(t, err)
	}
}

func TestReplaceVar(t *testing.T) {
	unittest.SmallTest(t)
	c := makeTaskCandidate("c", []string{"k:v"})
	c.Repo = "my-repo"
	c.Revision = "abc123"
	c.Name = "my-task"
	dummyId := "id123"
	require.Equal(t, "", replaceVars(c, "", dummyId))
	require.Equal(t, "my-repo", replaceVars(c, "<(REPO)", dummyId))
	require.Equal(t, "my-task", replaceVars(c, "<(TASK_NAME)", dummyId))
	require.Equal(t, "abc123", replaceVars(c, "<(REVISION)", dummyId))
	require.Equal(t, "<(REVISION", replaceVars(c, "<(REVISION", dummyId))
	require.Equal(t, "my-repo_my-task_abc123", replaceVars(c, "<(REPO)_<(TASK_NAME)_<(REVISION)", dummyId))
	require.Equal(t, dummyId, replaceVars(c, "<(TASK_ID)", dummyId))
	require.Equal(t, "", replaceVars(c, "<(PATCH_REF)", dummyId))

	c.Issue = "12345"
	c.Patchset = "3"
	c.Server = "https://server"
	require.Equal(t, "refs/changes/45/12345/3", replaceVars(c, "<(PATCH_REF)", dummyId))
}

func TestTaskCandidateJobs(t *testing.T) {
	unittest.SmallTest(t)

	c := taskCandidate{}
	now := time.Now().UTC()
	j1 := &types.Job{
		Created: now,
		Id:      "j1",
	}
	j2 := &types.Job{
		Created: now,
		Id:      "j2",
	}
	j3 := &types.Job{
		Created: now.Add(time.Second),
		Id:      "j3",
	}
	j4 := &types.Job{
		Created: now.Add(2 * time.Second),
		Id:      "j4",
	}

	for _, j := range []*types.Job{j1, j2, j3, j4} {
		require.False(t, c.HasJob(j))
	}

	c.AddJob(j3)
	require.Len(t, c.Jobs, 1)
	require.False(t, c.HasJob(j1))
	require.False(t, c.HasJob(j2))
	require.True(t, c.HasJob(j3))
	require.False(t, c.HasJob(j4))

	c.AddJob(j1)
	require.Len(t, c.Jobs, 2)
	require.True(t, c.HasJob(j1))
	require.False(t, c.HasJob(j2))
	require.True(t, c.HasJob(j3))
	require.False(t, c.HasJob(j4))
	require.Equal(t, []*types.Job{j1, j3}, c.Jobs)

	c.AddJob(j4)
	require.Len(t, c.Jobs, 3)
	require.True(t, c.HasJob(j1))
	require.False(t, c.HasJob(j2))
	require.True(t, c.HasJob(j3))
	require.True(t, c.HasJob(j4))
	require.Equal(t, []*types.Job{j1, j3, j4}, c.Jobs)

	c.AddJob(j2)
	require.Len(t, c.Jobs, 4)
	require.True(t, c.HasJob(j1))
	require.True(t, c.HasJob(j2))
	require.True(t, c.HasJob(j3))
	require.True(t, c.HasJob(j4))
	// Order is deterministic.
	require.Equal(t, []*types.Job{j1, j2, j3, j4}, c.Jobs)

	c.AddJob(j4)
	require.Len(t, c.Jobs, 4)
	c.AddJob(j2)
	require.Len(t, c.Jobs, 4)
	c.AddJob(j1)
	require.Len(t, c.Jobs, 4)

	for i := 5; i < 100; i++ {
		c.AddJob(&types.Job{
			Created: now.Add(time.Duration(i*23%7) * time.Second),
			Id:      fmt.Sprintf("j%d", i),
		})
	}
	last := time.Time{}
	for _, j := range c.Jobs {
		require.True(t, !last.After(j.Created))
		last = j.Created
	}
}
