package main

import (
	"context"
	"time"

	"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 BrSQLBackupDB() steps.Step {
	var (
		dstTidb            = &resource.ResourceHandle{}
		mcHost             = &resource.ResourceHandle{}
		backupOpts         = &host.BackupDbOpts{}
		backupLocalOpts    = &host.BackupDbOpts{}
		globalVariableOpts = &steps.TiDBVariableList
		mcRmOpts           = &host.McRmOpts{}
		uniq               = uuid.New().String()
	)
	semFalse := false
	semTrue := true
	return steps.
		NewBuilder().
		LoadEnv().
		LoadResourceFromEnv(utils.ResourcePrefix+"dst_tidb", dstTidb).
		LoadResourceFromEnv(utils.ParamPrefix+"br_opts", backupOpts).
		LoadResourceFromEnv(utils.ParamPrefix+"br_local_opts", backupLocalOpts).
		LoadResourceFromEnv(utils.ParamPrefix+"global_variable", globalVariableOpts).
		LoadResourceFromEnv(utils.ResourcePrefix+"mc", mcHost).
		LoadResourceFromEnv(utils.ParamPrefix+"mc_rm_opts", mcRmOpts).
		// disable sem for test
		ExecuteSQL(dstTidb, "", "create database if not exists br_sql_sem;").
		ExecuteSQL(dstTidb, "br_sql_sem", "create table if not exists t1 (id int);").
		ExecuteSQL(dstTidb, "br_sql_sem", "insert into t1 values (1);").
		EnableSem(dstTidb, &semFalse, 5 * time.Minute).
		EnableSem(dstTidb, &semTrue, 5 * time.Minute).
		ConfigGlobalVariable(globalVariableOpts, dstTidb).
		// failed backup local when sql sem enabled
		NewUniqPath(&mcRmOpts.Path, uniq).
		NewUniqPath(&backupLocalOpts.Storage, uniq).
		ExpectError(&semTrue, steps.NewBrSQLBackupDB(dstTidb, backupLocalOpts)).
		// backup to s3 will success
		NewUniqPath(&backupOpts.Storage, uniq).
		BrSQLBackupDB(dstTidb, backupOpts).
		McRemove(mcRmOpts, mcHost).
		Build()
}

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