package schedulers

import (
	"context"
	"encoding/json"
	"testing"

	"github.com/pingcap/test-infra/common/model/tcms/taskruns"

	commM "github.com/pingcap/test-infra/common/model"
	"github.com/pingcap/test-infra/services/tps/pkg/common"
	"github.com/stretchr/testify/assert"
)

var tc_spec string = `
           {
  "name": "upstream",
  "type": "TIDB_CLUSTER",
  "spec": {
    "pd": {
      "replicas": 1,
      "image": "hub.pingcap.net/qa/pd:{{variables.version}}"
    },
    "tikv": {
      "replicas": 1,
      "image": "hub.pingcap.net/qa/tikv:{{variables.version}}"
    },
    "tidb": {
      "replicas": 1,
      "image": "hub.pingcap.net/qa/tidb:{{variables.version}}"
    }
  }
}
`

func TestCompositeScheduler_Schedule(t *testing.T) {
	fifo := &FifoScheduler{}
	priority := &PriorityScheduler{}
	leaky := &LeakyScheduler{}

	s := &ChainScheduler{
		filterSchedulers:  []FilterScheduler{fifo, priority, leaky},
		refreshSchedulers: []RefreshScheduler{},
	}
	var jobs []*common.ArgoJob
	for i := 0; i < 10; i++ {
		jobs = append(jobs, &common.ArgoJob{
			PlanExec: &commM.TestPlanExecution{ID: commM.ID(i)},
			Plan: &commM.TestPlan{TestPlanBase: commM.TestPlanBase{
				TestBed: commM.TestBed{Items: []commM.TestBedItem{{Spec: json.RawMessage(tc_spec)}}}},
			},
			TestbedSetup: &taskruns.TestbedSetup{Status: taskruns.TestbedSetupStatus{Schedule: &taskruns.Schedule{}}},
		})
	}
	scheduled, err := s.Filter(context.TODO(), jobs)
	assert.NoError(t, err)
	assert.Equal(t, MaxJobPerMin, len(scheduled), "should be $MaxJobPerMin")
}

func TestFifo(t *testing.T) {
	var jobs []*common.ArgoJob
	for i := 0; i < 3; i++ {
		jobs = append(jobs, &common.ArgoJob{PlanExec: &commM.TestPlanExecution{ID: commM.ID(i), CreatedAt: commM.Timestamp(100 - i)}, Plan: &commM.TestPlan{TestPlanBase: commM.TestPlanBase{
			TestBed: commM.TestBed{Items: []commM.TestBedItem{{Spec: json.RawMessage(tc_spec)}}},
		}}})
	}
	fifo := &FifoScheduler{}
	assert.EqualValues(t, 0, jobs[0].ID())
	jobs, err := fifo.Filter(context.TODO(), jobs)
	assert.NoError(t, err)
	assert.EqualValues(t, 2, jobs[0].ID())
}
