package ccb_application_router

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

	. "github.com/onsi/gomega"
	"github.com/pingcap/endless/pkg/workloadnode"
	"github.com/pingcap/log"
	"github.com/pingcap/test-infra/sdk/core"
	"github.com/pingcap/test-infra/sdk/resource"
)

func ImporterClientPrepareData(suiteTestCtx core.TestContext, ctx context.Context) error {
	// Importer Workload Client downloads indexInfo data to load in rawkv cluster
	// indexInfo data has been already uploaded into minio.
	// Since unzip is time-consuming, so start to unzip at the beginning of this testcase
	importerClient := suiteTestCtx.Resource("ccbloadimport").(resource.WorkloadNode)
	options := resource.WorkloadNodeExecOptions{Command: "[ -f ./data/indexInfo_data_sorted.tar.gz ]"}
	_, _, exitCode, _ := importerClient.Exec(options)
	if exitCode == 0 {
		log.Info("indexInfo_data_sorted.tar.gz file has been downloaded before")
	} else {
		cmds := [...]string{"mc config host add minio http://minio.pingcap.net:9000 minioadmin minioadmin",
			"mc cp minio/rawkv-ccb-app-router/indexInfo_data_sorted.tar.gz ./data/",
		}
		for _, cmd := range cmds {
			if err := workloadnode.CommandContext(ctx, cmd).Run(importerClient); err != nil {
				return err
			}
		}
	}
	options = resource.WorkloadNodeExecOptions{Command: "ls ./data/indexInfo_data_sorted/| wc -l"}
	stdout, _, _, _ := importerClient.Exec(options)
	log.S().Infof("Data File Count: %s", stdout)
	dataFileCount, _ := strconv.ParseInt(stdout, 10, 0)
	if dataFileCount < 1000 {
		if err := workloadnode.CommandContext(ctx, "tar zxf ./data/indexInfo_data_sorted.tar.gz -C ./data/").Run(importerClient); err != nil {
			return err
		}
	}
	return nil
}

func ImportData(suiteTestCtx core.TestContext, ctx context.Context, importConfigFileName string, pdClientAddr string, times int, stageDesc string) TestCaseStageInfo {
	stage := TestCaseStageInfo{
		Description: stageDesc,
		Start:       time.Now(),
	}

	// Importer Workload Client downloads indexInfo data to load in rawkv cluster
	// indexInfo data has been already uploaded into minio.
	// Since unzip is time-consuming, so start to unzip at the beginning of this testcase
	importerClient := suiteTestCtx.Resource("ccbloadimport").(resource.WorkloadNode)
	cmd := fmt.Sprintf("java -Xmx2048M -Dp='/usr/src/rawkvworkload/configs/%s' -Dpd='%s' -jar /usr/src/rawkvworkload/libs/tikv_importer_v1.2.2_20220215.jar > /usr/src/rawkvworkload/log/%s_%v.log", importConfigFileName, pdClientAddr, importConfigFileName, times)

	options := resource.WorkloadNodeExecOptions{Command: cmd}
	_, _, _, err := importerClient.Exec(options)
	stage.End = time.Now()
	Expect(err).Should(BeNil())
	cmd = fmt.Sprintf("tail /usr/src/rawkvworkload/log/%s_%v.log", importConfigFileName, times)
	options = resource.WorkloadNodeExecOptions{Command: cmd}
	stdout, _, execCode, err := importerClient.Exec(options)
	log.S().Infof("import data log: %s, execCode: %v", stdout, execCode)
	Expect(err).Should(BeNil())
	Expect(execCode).Should(Equal(0))
	Expect(strings.Contains(stdout, "ERROR")).Should(BeFalse())
	return stage
}

func SetImporterRW(suiteTestCtx core.TestContext, ctx context.Context, pdClientAddr string, RWMode string) {
	var cmd string
	if RWMode == "onlyread" {
		cmd = fmt.Sprintf("java -Xmx2048M -Dp='configs/importer-onlyread-true.properties' -Dpd='%s' -jar libs/tikv_importer_v1.2.2_20220215.jar", pdClientAddr)
	} else {
		cmd = fmt.Sprintf("java -Xmx2048M -Dp='configs/importer-onlyread-false.properties' -Dpd='%s' -jar libs/tikv_importer_v1.2.2_20220215.jar", pdClientAddr)
	}
	importerClient := suiteTestCtx.Resource("ccbloadimport").(resource.WorkloadNode)
	options := resource.WorkloadNodeExecOptions{Command: cmd}
	stdout, _, execCode, err := importerClient.Exec(options)
	log.S().Infof("SetImporterRW stdout: %s, execCode: %v, err: %v", stdout, execCode, err)
	Expect(execCode).Should(Equal(0))
	Expect(err).Should(BeNil())
	Expect(strings.Contains(stdout, "ERROR")).Should(BeFalse())
}
