package ddl

import (
	"context"
	"errors"
	"io"
	"math/rand"
	"strings"
	"time"

	. "github.com/onsi/gomega"
	. "github.com/pingcap/endless/pkg/util"
	"github.com/pingcap/endless/pkg/workloadnode/cluster"
	"github.com/pingcap/endless/testcase/oltp/oltppkg"
	"github.com/pingcap/log"
	"golang.org/x/sync/errgroup"
)

func OLTP_ADD_INDEX_FUN_001(
	ctx context.Context,
	tc cluster.BaseCluster,
	pr *io.PipeReader,
	caseCmdParms oltppkg.CaseCmdParms,
) {
	oltppkg.CancelAllDDLTasks(ctx, tc)
	defer oltppkg.CancelAllDDLTasks(ctx, tc)
	var (
		tableNum           int
		addIndexTable      string
		addIndexColumnName string
		useDb              string
	)
	workloadType := caseCmdParms.WorkloadType.Type[0]
	if strings.HasPrefix(workloadType, "sysbench_") {
		useDb = caseCmdParms.SysbenchParms.Db
		tableNum = caseCmdParms.SysbenchParms.TableNum
		tables := oltppkg.GetAllTablesNames(ctx, tc, useDb)
		rand.Seed(time.Now().UnixNano())
		addIndexTable = tables[rand.Intn(tableNum)]
		addIndexColumnName = "c"
	} else if strings.HasPrefix(workloadType, "ycsb") {
		useDb = caseCmdParms.YcsbParms.Db
		addIndexTable = "usertable"
		addIndexColumnName = "FIELD0"
	} else if strings.HasPrefix(workloadType, "tpcc") {
		useDb = caseCmdParms.TpccParms.Db
		addIndexTable = "orders"
		addIndexColumnName = "o_carrier_id"
	} else {
		err := errors.New("invalid workloadType")
		Expect(err).Should(Succeed())
	}

	runTime := 40 * time.Minute
	warmUpTime := 10 * time.Minute
	ctxAll, cancel := context.WithTimeout(ctx, runTime)
	defer cancel()
	g, ctxg := errgroup.WithContext(ctxAll)

	oltppkg.FunCommonCheck(ctxg, tc, g, runTime, pr)

	g.Go(WithGinkgoRecover(func() {
		oltppkg.WaitFor(ctxg, "wait for adding index, which is 2min later than qps check", warmUpTime)
		AddIndexForTable(ctxg, tc, runTime, useDb, addIndexTable, addIndexColumnName)
		oltppkg.CancelAllDDLTasks(ctx, tc)
		log.Info("add index exit.")
	}))

	Expect(g.Wait()).Should(BeNil())
}
