package tikv_br

import (
	"context"
	"fmt"
	"strings"
	"time"

	. "github.com/pingcap/endless/pkg/matcher"
	. "github.com/pingcap/endless/testcase/oltp/oltppkg"
	"github.com/pingcap/test-infra/sdk/resource"
)

const (
	BrTimeout = time.Duration(30) * time.Minute
)

type TiKVBrRunCmd struct {
	brPath    string
	options   []string
	command   string
	accessid  string
	accesskey string
}

func NewTiKVBr(brPath string, command string, accessid string, accesskey string) *TiKVBrRunCmd {
	b := &TiKVBrRunCmd{command: command, accessid: accessid, accesskey: accesskey, brPath: brPath}
	// b.options = append(b.options, "--send-credentials-to-tikv=true")
	return b
}

func (b *TiKVBrRunCmd) Pd(pd string) *TiKVBrRunCmd {
	b.options = append(b.options, fmt.Sprintf("--pd %s", pd))
	return b
}

func (b *TiKVBrRunCmd) Storage(storage string) *TiKVBrRunCmd {
	b.options = append(b.options, fmt.Sprintf("--storage %s", storage))
	return b
}

func (b *TiKVBrRunCmd) S3endpoint(s3endpoint string) *TiKVBrRunCmd {
	b.options = append(b.options, fmt.Sprintf("--s3.endpoint  %s", s3endpoint))
	return b
}

func (b *TiKVBrRunCmd) LogFile(logFile string) *TiKVBrRunCmd {
	b.options = append(b.options, fmt.Sprintf("--log-file  %s", logFile))
	return b
}

func (b *TiKVBrRunCmd) DstApiVersion(dstApiVersion string) *TiKVBrRunCmd {
	b.options = append(b.options, fmt.Sprintf("--dst-api-version  %s", dstApiVersion))
	return b
}

func (b *TiKVBrRunCmd) Checksum(check bool) *TiKVBrRunCmd {
	checkStr := "false"
	if check {
		checkStr = "true"
	}
	b.options = append(b.options, fmt.Sprintf("--checksum=%s", checkStr))
	return b
}

func (b *TiKVBrRunCmd) CheckReq(checkReq bool) *TiKVBrRunCmd {
	b.options = append(b.options, fmt.Sprintf("--check-requirements=%t", checkReq))
	return b
}

func (t *TiKVBrRunCmd) Command(command string) *TiKVBrRunCmd {
	t.command = command
	return t
}

func (s *TiKVBrRunCmd) Build() string {
	return fmt.Sprintf("export AWS_ACCESS_KEY_ID=%s;export AWS_SECRET_ACCESS_KEY=%s;%s %s %s",
		s.accessid, s.accesskey, s.brPath, s.command, strings.Join(s.options[:], " "))
}

func TiKVBackupRawData(ctx context.Context, pdAddr string, brPath string, br resource.BR,
	s3Parms S3Parms, storage string, dstApiVersion string) {

	ctxbr, cancel := context.WithTimeout(ctx, BrTimeout)
	defer cancel()

	tikvBrCmd := NewTiKVBr(brPath, "backup raw", s3Parms.S3AccessKeyID, s3Parms.S3SecretAccessKey)
	tikvBrCmdStr := tikvBrCmd.Pd(pdAddr).
		Storage(storage).
		S3endpoint(s3Parms.S3Endpoint).
		CheckReq(false).
		DstApiVersion(dstApiVersion).
		Checksum(true).
		Build()
	Try(ExecWorkloadCmd(ctxbr, br, tikvBrCmdStr, true, nil))
}

func TiKVRestoreRawData(ctx context.Context, pdAddr string, brPath string, br resource.BR,
	s3Parms S3Parms, storage string) {
	ctxbr, cancel := context.WithTimeout(ctx, BrTimeout)
	defer cancel()

	tikvBrCmd := NewTiKVBr(brPath, "restore raw", s3Parms.S3AccessKeyID, s3Parms.S3SecretAccessKey)
	tikvBrCmdStr := tikvBrCmd.Pd(pdAddr).
		Storage(storage).
		S3endpoint(s3Parms.S3Endpoint).
		CheckReq(false).
		Checksum(true).
		Build()
	Try(ExecWorkloadCmd(ctxbr, br, tikvBrCmdStr, true, nil))
}
