package main

import (
	"context"

	"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 ParallelImportMaxError() steps.Step {
	var (
		tidbRes            = &resource.ResourceHandle{}
		lightningRes       = &resource.ResourceHandle{}
		lightningRes2      = &resource.ResourceHandle{}
		opts               = &steps.LightningImportOpts{}
		opts2              = &steps.LightningImportOpts{}
		globalVariableOpts = &steps.TiDBVariableList
		dropDatabases      string
		adminCheck         string
		maxErrorRows       int32
		maxErrorSchema     string
		expectError        bool
	)

	p := steps.NewParallel(steps.NewLightningImport(opts, lightningRes, tidbRes),
		steps.NewLightningImport(opts2, lightningRes2, tidbRes))

	return steps.
		NewBuilder().
		LoadEnv().
		LoadParamFromEnv(utils.ParamPrefix+"drop_databases", &dropDatabases).
		LoadResourceFromEnv(utils.ParamPrefix+"import_basic_opts", opts).
		LoadResourceFromEnv(utils.ParamPrefix+"import_basic_opts2", opts2).
		LoadResourceFromEnv(utils.ResourcePrefix+"target", tidbRes).
		LoadResourceFromEnv(utils.ResourcePrefix+"lightning", lightningRes).
		LoadResourceFromEnv(utils.ResourcePrefix+"lightning2", lightningRes2).
		LoadParamFromEnv(utils.ParamPrefix+"admin_check", &adminCheck).
		LoadResourceFromEnv(utils.ParamPrefix+"global_variable", &globalVariableOpts).
		LoadResourceFromEnv(utils.ParamPrefix+"max_error_rows", &maxErrorRows).
		LoadParamFromEnv(utils.ParamPrefix+"max_error_schema", &maxErrorSchema).
		LoadResourceFromEnv(utils.ParamPrefix+"expect_error", &expectError).
		ConfigGlobalVariable(globalVariableOpts, tidbRes).
		DropUserDatabases(tidbRes).
		// lightning passes if max-error >= actual errors, otherwise it fails.
		ExpectError(&expectError, p).
		// check whether max-error records as expected
		CheckLightningMaxError(&maxErrorRows, &maxErrorSchema, tidbRes).
		// Pass opts.Crc32Checksum = 0 to skip checksum if needed (when lighting import failed if max-error not on or less than actual errors.
		CheckDatabasesCrc32(&opts.Crc32Checksum, &dropDatabases, tidbRes).
		AdminCheck(tidbRes, &adminCheck).
		DropUserDatabases(tidbRes).
		Build()
}

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