package qhad

import (
	"context"

	"github.com/pingcap/test-infra/sdk/core"
	"github.com/pingcap/test-infra/sdk/resource"
	"golang.org/x/sync/errgroup"

	"github.com/pingcap/endless/pkg/workloadnode"
	"github.com/pingcap/endless/pkg/workloadnode/cmdstr"
)

// TODO: So much duplicate code with betting.RunWorkload, maybe we can can
// unify them into one.
func RunWorkload(
	suiteTestCtx core.TestContext,
	tc resource.TiDBCluster,
	ctx context.Context,

	opts cmdstr.QHAdOptions,
	subcmd cmdstr.GoycsbSubcmd,
) error {
	g, gctx := errgroup.WithContext(ctx)

	dbURL, err := tc.ServiceURL(resource.DBAddr)
	if err != nil {
		return err
	}
	opts.MySQL.Host = dbURL.Hostname()
	opts.MySQL.Port = dbURL.Port()

	wn := suiteTestCtx.Resource("workload0").(resource.WorkloadNode)

	goycsb := cmdstr.NewGoycsb("/go-ycsb")
	if subcmd == cmdstr.GoycsbLoad {
		goycsb.Load("mysql")
	} else {
		goycsb.Run("mysql")
	}
	cmdString := goycsb.QHAdOptions(&opts).String()
	cmd := workloadnode.CommandContext(gctx, cmdString)

	// HACK: Kill old go-ycsb process.
	if err := workloadnode.CommandContext(ctx, "pkill -9 go-ycsb || true").Run(wn); err != nil {
		return nil
	}

	// Start client on workloadnode.
	if err := cmd.Start(wn); err != nil {
		return err
	}

	g.Go(func() error {
		return cmd.Wait()
	})

	return g.Wait()
}
