package cc

import (
	"time"

	"github.com/google/uuid"
	"github.com/pingcap/test-infra/caselib/pkg/host"
	"github.com/pingcap/test-infra/caselib/pkg/model/ticdc"
	"github.com/pingcap/test-infra/caselib/pkg/model/workload"
	"github.com/pingcap/test-infra/caselib/pkg/steps"
	"github.com/pingcap/test-infra/caselib/pkg/utils"
	"github.com/pingcap/test-infra/caselib/ticdc/common"
	"github.com/pingcap/test-infra/common/model/resource"
	"github.com/pingcap/tiflow/cdc/model"
)

// CDC works parallelized with BR backup upstream or restore downstream
// Create upstream TiDB cluster/downstream TiDB/workload/br/mc
// Create a changefeed
// Create database named `workload`
// Run workload prepare
// Run BR backup upstream parallelized with workload run (CDC has sync task to work)
// Run BR restore downstream parallelized with workload run (CDC has sync task to work)
// Waiting for workload finish
// Check consistency
func CCCDCBRParallelized() steps.Step {
	var (
		// changeFeedID = "cc-dc-br-parallelized"
		brHost               = &resource.ResourceHandle{}
		mcHost               = &resource.ResourceHandle{}
		backupOpts           = &host.BackupFullOpts{}
		dbName               = "CCBP"
		backupDownstreamOpts = &host.BackupFullOpts{}
		mcRmOpts             = &host.McRmOpts{}
		uniq                 = uuid.New().String()
	)
	return steps.
		NewBuilder().
		LoadEnv().
		LoadResourceFromEnv("TI_PARAM_RES_upstream", common.ResourceHandleSource).
		LoadResourceFromEnv("TI_PARAM_RES_downstream", common.ResourceHandleMySQL).
		LoadResourceFromEnv("TI_PARAM_RES_workload", common.ResourceHandleWorkload).
		LoadResourceFromEnv(utils.ResourcePrefix+"br", brHost).
		LoadResourceFromEnv(utils.ResourcePrefix+"mc", mcHost).
		LoadResourceFromEnv(utils.ParamPrefix+"br_opts", backupOpts).
		NewUniqPath(&backupOpts.Storage, uniq).
		NewUniqPath(&mcRmOpts.Path, uniq).
		NewUniqPath(&backupDownstreamOpts.Storage, uniq).
		NewUniqPath(&mcRmOpts.Path, uniq).
		CreateDatabase(common.ResourceHandleSource, dbName).
		InitCDCComponents(common.ResourceHandleSource, common.ResourceHandleMySQL).
		// OperateChangeFeed(&ticdc.ChangeFeedCreateFlags{SinkType: ticdc.SinkTypeMySQL, ID: changeFeedID}).
		InitWorkload(common.ResourceHandleWorkload).
		Parallel(
			steps.NewBrBackupFull(brHost, common.ResourceHandleSource, backupOpts),
			steps.NewRunWorkload(&workload.QihooOption{
				Command:        workload.CommandTypeRun,
				PropertyFile:   "./workloads/betting", // property file is located inside cc workload image
				PropertyValues: []string{"operationcount=500000", "dbnameprefix=" + common.DBNameccPrefix, "tablecount=20", "unitnameprefix=unit2_", "unitscount=10", "databaseproportions=1.0", "exectime=3600"},
				Threads:        20,
				Duration:       3 * time.Hour, // we do not know how long the command will take, set it to 8 at the moment.
			}),
			steps.NewBrBackupFull(brHost, common.ResourceHandleMySQL, backupDownstreamOpts),
			steps.NewSwitchOwner(common.ResourceHandleSource, 20*time.Second),
			steps.NewRunWorkload(&workload.QihooOption{
				Command:        workload.CommandTypeRun,
				PropertyFile:   "./workloads/betting", // property file is located inside cc workload image
				PropertyValues: []string{"operationcount=500000", "dbnameprefix=" + common.DBNameccPrefix, "tablecount=20", "unitnameprefix=unit2_", "unitscount=10", "databaseproportions=1.0", "exectime=3600"},
				Threads:        20,
				Duration:       3 * time.Hour, // we do not know how long the command will take, set it to 8 at the moment.
			}),
		).
		OperateChangeFeed(&ticdc.ChangeFeedAdminJobFlags{JobType: model.AdminStop, ID: common.ChangefeedMySQLcc}).
		Sleep(30*time.Minute).
		OperateChangeFeed(&ticdc.ChangeFeedAdminJobFlags{JobType: model.AdminResume, ID: common.ChangefeedMySQLcc}).
		SendFinishMark(dbName).
		WaitFinishMark(common.ResourceHandleMySQL, dbName, 3*time.Hour).
		CheckConsistency(common.ResourceHandleSource, common.ResourceHandleMySQL, dbName).
		Build()
}
