package main

import (
	"context"

	"github.com/google/uuid"
	"github.com/pingcap/test-infra/caselib/pkg/host"
	"github.com/pingcap/test-infra/caselib/pkg/steps"
	"github.com/pingcap/test-infra/caselib/pkg/utils"
	"github.com/pingcap/test-infra/common/model/resource"
	_ "github.com/pingcap/test-infra/sdk/resource/impl/k8s"
	"go.uber.org/zap"
)

func BrRateLimit() steps.Step {
	var (
		dstTidb       = &resource.ResourceHandle{}
		brHost        = &resource.ResourceHandle{}
		lightningRes  = &resource.ResourceHandle{}
		mcHost        = &resource.ResourceHandle{}
		lightningOpts = &steps.LightningImportOpts{}
		backupOpts    = &host.BackupFullOpts{}
		mcRmOpts      = &host.McRmOpts{}
		uniq          = uuid.New().String()
		dropDatabases string
		output        string
	)

	return steps.
		NewBuilder().
		LoadEnv().
		LoadResourceFromEnv(utils.ResourcePrefix+"dst_tidb", dstTidb).
		LoadResourceFromEnv(utils.ResourcePrefix+"br", brHost).
		LoadResourceFromEnv(utils.ResourcePrefix+"mc", mcHost).
		LoadResourceFromEnv(utils.ResourcePrefix+"lightning", lightningRes).
		LoadParamFromEnv(utils.ParamPrefix+"drop_databases", &dropDatabases).
		LoadResourceFromEnv(utils.ParamPrefix+"br_opts", backupOpts).
		LoadResourceFromEnv(utils.ParamPrefix+"mc_rm_opts", mcRmOpts).
		NewUniqPath(&backupOpts.Storage, uniq).
		NewUniqPath(&mcRmOpts.Path, uniq).
		LoadResourceFromEnv(utils.ParamPrefix+"import_basic_opts", lightningOpts).
		DropDatabasesIfExists(dstTidb, &dropDatabases).
		LightningImport(lightningOpts, lightningRes, dstTidb).
		BrBackupFull(brHost, dstTidb, backupOpts).
		ExtractValue(&backupOpts.Stdout, "average-speed=", "MB/s", &output).
		AssertValue(&output, steps.Less, 15.0).
		DropDatabasesIfExists(dstTidb, &dropDatabases).
		BrRestoreFull(brHost, dstTidb, backupOpts).
		ExtractValue(&backupOpts.Stdout, "average-speed=", "MB/s", &output).
		AssertValue(&output, steps.Less, 12.0).
		CheckDatabasesCrc32(&backupOpts.Crc32Checksum, &dropDatabases, dstTidb).
		McRemove(mcRmOpts, mcHost).
		Build()
}

func main() {
	_, logger := utils.GetCtxAndLogger()
	ctx := steps.New(context.Background())
	if err := BrRateLimit().Execute(ctx); err != nil {
		logger.Fatal("BrRateLimit failed", zap.Error(err))
	}
	logger.Info("BrRateLimit passed")
}
