package workload

import (
	"context"
	"database/sql"
	"fmt"
	"strconv"
	"time"

	. "github.com/onsi/gomega"
	. "github.com/pingcap/endless/pkg/matcher"
	"github.com/pingcap/log"
	"go.uber.org/zap"
	"golang.org/x/sync/errgroup"

	// . "github.com/pingcap/endless/pkg/matcher/metrics"
	. "github.com/pingcap/endless/pkg/util"
	"github.com/pingcap/endless/pkg/workload"
	"github.com/pingcap/endless/testcase/oltp/oltppkg"
	"github.com/pingcap/endless/testcase/oltp/systemtest/ddl"

	// "github.com/pingcap/log"
	"github.com/pingcap/test-infra/sdk/core"
	"github.com/pingcap/test-infra/sdk/resource"
	_ "github.com/pingcap/test-infra/sdk/resource/impl/k8s"
)

func OLTP_BIG_VALUE_INSERT(
	ctx core.TestContext,
	tc resource.MySQLCompatible,
	caseCmdParms oltppkg.CaseCmdParms,
	workloadRunParms oltppkg.WorkloadRunParms,
) {
	timestamp := strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
	dbName := fmt.Sprintf("%s_%s", "big_value", timestamp)
	Try(oltppkg.RecreateDatabase(ctx, tc, dbName))
	db := Try(ddl.ConnectDbWithTimeout(tc, dbName, "timeout=300m", "readTimeout=300m", "writeTimeout=300m")).(*sql.DB)
	defer db.Close()
	var runTime time.Duration
	if caseCmdParms.RunTime.TotalRunTime != 0 {
		runTime = caseCmdParms.RunTime.TotalRunTime
	} else {
		runTime = 1 * time.Hour
	}
	qpsJitterCheckParms := oltppkg.QpsJitterCheckParameters{
		IsCheck: false,
	}
	durJitterCheckParms := oltppkg.DurJitterCheckParameters{
		IsCheck: false,
	}
	log.Info("test will", zap.Duration("run", runTime))
	ctxAll, cancel := context.WithTimeout(ctx, runTime)
	defer cancel()
	g, gctx := errgroup.WithContext(ctxAll)

	w := workload.AppendWorkload{
		DB:          db,
		Concurrency: 256,
		Tables:      256,
		PadLength:   4000000,
	}
	oltppkg.FunCommonCheck(gctx, tc, g, runTime, nil, qpsJitterCheckParms, durJitterCheckParms)

	Try(w.Prepare())
	g.Go(WithGinkgoRecover(func() {
		w.Run(gctx)
		cancel()
	}))
	Expect(g.Wait()).Should(BeNil())
}
