package main

import (
	"context"

	"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 ImportAutoHandleSchema() steps.Step {
	var (
		tidbRes            = &resource.ResourceHandle{}
		mc                 = &resource.ResourceHandle{}
		lightningRes       = &resource.ResourceHandle{}
		opts               = &steps.LightningImportOpts{}
		opts2              = &steps.LightningImportOpts{}
		globalVariableOpts = &steps.TiDBVariableList
		loaderOpts         = &host.LoaderOpts{}
		mcCopyOpts         = &host.McCopyOpts{}
		dropDatabases      string
		adminCheck         string
	)

	return steps.
		NewBuilder().
		LoadEnv().
		LoadResourceFromEnv(utils.ResourcePrefix+"target", tidbRes).
		LoadResourceFromEnv(utils.ResourcePrefix+"lightning", lightningRes).
		LoadResourceFromEnv(utils.ResourcePrefix+"mc", mc).
		LoadResourceFromEnv(utils.ParamPrefix+"loader_opts", loaderOpts).
		LoadResourceFromEnv(utils.ParamPrefix+"mc_copy_opts", mcCopyOpts).
		LoadResourceFromEnv(utils.ParamPrefix+"import_basic_opts", opts).
		LoadResourceFromEnv(utils.ParamPrefix+"import_basic_opts", opts2).
		LoadParamFromEnv(utils.ParamPrefix+"drop_databases", &dropDatabases).
		LoadParamFromEnv(utils.ParamPrefix+"admin_check", &adminCheck).
		LoadResourceFromEnv(utils.ParamPrefix+"global_variable", &globalVariableOpts).
		DropDatabasesIfExists(tidbRes, &dropDatabases).
		ConfigGlobalVariable(globalVariableOpts, tidbRes).
		// Verify lightning can automatically handle no-schema parameters, as long as schema can be found in either TiDB or Data source.
		// 1, There is table schema but no DB schema in data source, while there is DB schema and no table schema in target TiDB
		ExecuteSQL(tidbRes, "", "create database if not exists sbtest;").
		LightningImport(opts, lightningRes, tidbRes).
		CheckDatabasesCrc32(&opts.Crc32Checksum, &dropDatabases, tidbRes).
		AdminCheck(tidbRes, &adminCheck).
		// 2,  There are DB and schema file in data source, and there are db and some table schemas in target TiDB
		DropDatabasesIfExists(tidbRes, &dropDatabases).
		McCopy(mcCopyOpts, mc).
		ExecuteSQL(tidbRes, "", "create database if not exists tidb_loader").
		LoaderToMySQL(mc, tidbRes, loaderOpts).
		ExecuteSQL(tidbRes, "", "drop database if exists tidb_loader").
		LightningImport(opts2, lightningRes, tidbRes).
		CheckDatabasesCrc32(&opts.Crc32Checksum, &dropDatabases, tidbRes).
		AdminCheck(tidbRes, &adminCheck).
		Build()
}

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