package tiupscale

import (
	"fmt"
	"net/url"
	"strings"
	"time"

	. "github.com/onsi/gomega"
	. "github.com/pingcap/endless/pkg/matcher"
	"github.com/pingcap/endless/pkg/workloadnode/tiup"
	"github.com/pingcap/endless/testcase/oltp/oltppkg"
	"github.com/pingcap/endless/testcase/oltp/systemtest/scale"
	"github.com/pingcap/log"
	"github.com/pingcap/test-infra/sdk/core"
	"github.com/pingcap/test-infra/sdk/resource"
	"go.uber.org/zap"
)

func OLTP_SCALE_OUT_TIUP(ctx core.TestContext,
	tc *tiup.TiUPCluster,
	workloadRunParms oltppkg.WorkloadRunParms,
	caseCmdParms oltppkg.CaseCmdParms,
) {
	scaleParams := ScaleParameters{
		ScaleType:       "out",
		ScaleOutTopo:    ScaleOutTopo,
		QpsDropLessThan: 0.9,
		QpsCheckTime:    2 * time.Minute,
	}
	caseCmdParms.RunTime = oltppkg.RunTime{
		TotalRunTime: 3 * time.Hour,
		WarmUpTime:   10 * time.Minute,
		RecoveryTime: 10 * time.Minute,
	}
	TiupRunScaleTest(ctx, tc, caseCmdParms, scaleParams, workloadRunParms)
	log.Info("Begin to check the stombestone")
	promURL := Try(tc.ServiceURL(resource.Prometheus)).(*url.URL)
	upStoreNum := scale.GetUpStoreNum(promURL)
	Expect(upStoreNum).Should(BeNumerically("==", 6))

}

func OLTP_SCALE_IN_TIUP(ctx core.TestContext,
	tc *tiup.TiUPCluster,
	workloadRunParms oltppkg.WorkloadRunParms,
	caseCmdParms oltppkg.CaseCmdParms) {

	scaleInList := strings.Split("tikv4-peer:20160,tikv5-peer:20160,tikv6-peer:20160,tidb3-peer:4000,tidb4-peer:4000", ",")
	scaleParams := ScaleParameters{
		ScaleType:       "in",
		ScaleInList:     scaleInList,
		QpsDropLessThan: 0.6,
		QpsCheckTime:    10 * time.Minute,
	}
	caseCmdParms.RunTime = oltppkg.RunTime{
		TotalRunTime: 3 * time.Hour,
		WarmUpTime:   10 * time.Minute,
		RecoveryTime: 10 * time.Minute,
	}
	TiupRunScaleTest(ctx, tc, caseCmdParms, scaleParams, workloadRunParms)

	log.Info("Begin to check the stombestone")
	meta := tc.ClusterInfo.ClusterMeta
	tc.ControlNodeHost.Run(fmt.Sprintf("tiup cluster prune %s -y", meta.ClusterName), 10*time.Minute)

	promURL := Try(tc.ServiceURL(resource.Prometheus)).(*url.URL)
	tombestoneNum := scale.GetTombstoneNum(promURL)
	Expect(tombestoneNum).Should(BeNumerically("==", 3))
	output := Try(oltppkg.BasicClusterExecPdCtl(tc, "store remove-tombstone")).(string)
	log.Info("pd exec command output", zap.String("output", output))
	Expect(strings.Contains(output, "Success")).Should(BeTrue())
	oltppkg.WaitFor(ctx, "waiting for tombstone removed", 2*time.Minute)
	Expect(scale.GetTombstoneNum(promURL)).Should(BeNumerically("==", 0))
	oltppkg.CheckClusterHealth(tc)

}
