package main

import (
	"context"
	"flag"
	"fmt"
	"math/rand"
	"os"
	"os/signal"
	"syscall"
	"time"

	client "github.com/pingcap/schrodinger/pkg/test_client"
)

var (
	mode      = flag.String("mode", "online", "case mode, support values: online / dev, default value: online")
	dbName    = flag.String("db", "test", "database name")
	timeLimit = flag.Duration("time-limit", time.Hour, "how long to run the test")
	tableSize = flag.Int("table-size", 10000, "how large is the table to run the test")
	threads   = flag.Int("threads", 64, "how many threads to run the test concurrently")
)

func main() {
	client.Info("[txn_keep_alive] start txn_keep_alive test")
	flag.Parse()
	rand.Seed(time.Now().Unix())

	ctx, cancel := context.WithTimeout(context.Background(), *timeLimit)
	cli := client.New(ctx, func(mode string) (clientMode client.Mode) {
		switch client.Mode(mode) {
		case client.ModeOnline:
			clientMode = client.ModeOnline
		case client.ModeDev:
			clientMode = client.ModeDev
		default:
			client.Fatalf("[txn_keep_alive] Invalid mode: %v,support values: online / dev", mode)
		}
		client.Info("Mode:", clientMode)
		return clientMode
	}(*mode))

	dbAddr := cli.TiDBService()
	dbDSN := fmt.Sprintf("root:@tcp(%s)/%s", dbAddr, *dbName)

	sc := make(chan os.Signal, 1)
	signal.Notify(sc,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT)
	go func() {
		sig := <-sc
		client.Infof("[txn_keep_alive] Got signal [%s] to exist.", sig)
		cancel()
		os.Exit(0)
	}()

	testCase := NewTxnKeepAliveCase(dbDSN, *tableSize, *threads)
	if err := testCase.Initialize(ctx); err != nil {
		client.Fatalf("[txn_keep_alive] initial failed %+v", err)
	}

	innerCtx, innerCancel := context.WithCancel(context.Background())
	finishCh := make(chan error)
	go func() {
		finishCh <- testCase.Execute(innerCtx)
	}()

	select {
	case <-ctx.Done():
		client.Info("[txn_keep_alive] Test finished")
		innerCancel()
	case err := <-finishCh:
		if err != nil {
			client.Fatalf("[txn_keep_alive] return with error %+v", err)
		}
	}
}
