package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/pingcap/schrodinger-test/util"
	"github.com/pingcap/schrodinger/pkg/test_client"
	"golang.org/x/net/context"
)

var defaultPushMetricsInterval = 15 * time.Second
var (
	dbName     = flag.String("db", "sbtest", "database name")
	tableCount = flag.Int("table-count", 16, "number of tables")
	tableSize  = flag.Int("table-size", 1000000, "number of rows per table")
	threads    = flag.Int("threads", 256, "number of threads to use")
	maxTime    = flag.Int("max-time", 2400, "limit fo total exection time in seconds")
	interval   = flag.Duration("interval", 2*time.Hour, "interval to run sysbench")
	luaPath    = flag.String("lua-path", ".", "the path of the lua scripts")
)

func main() {
	client.Info("[sysbench] start...")
	flag.Parse()
	ctx, cancel := context.WithCancel(context.Background())
	cli := client.New(ctx, client.ModeOnline)
	sc := make(chan os.Signal, 1)
	signal.Notify(sc,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT)
	go func() {
		sig := <-sc
		client.Infof("Got signal [%d] to exist", sig)
		cancel()
		os.Exit(0)
	}()

	lbService := cli.TiDBService()

	addrs := strings.Split(strings.TrimSpace(lbService), ":")
	if len(addrs) < 2 {
		client.Fatalf("[sysbench] %s is invalid", addrs)
	}
	port, err := strconv.Atoi(addrs[1])
	if err != nil {
		client.Fatalf("[sysbench] %s is invalid", addrs)
	}

	metricsAddr := cli.PrometheusAddr()
	if len(metricsAddr) > 0 {
		go util.PushPrometheus("sysbench", metricsAddr, defaultPushMetricsInterval)
	}

	cfg := Config{
		Host:       addrs[0],
		Port:       port,
		User:       "root",
		TableCount: *tableCount,
		TableSize:  *tableSize,
		Threads:    *threads,
		MaxTime:    *maxTime,
		Interval:   *interval,
		DBName:     *dbName,
		LuaPath:    *luaPath,
	}
	sysbench := NewSysbenchCase(&cfg)
	dbAddr := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", sysbench.cfg.User, sysbench.cfg.Password, sysbench.cfg.Host, sysbench.cfg.Port, "sbtest")
	sysbench.db, err = util.OpenDB(dbAddr, 2)
	if err != nil {
		client.Fatalf("[sysbench]open db failed: %v", err)
	}
	if err := sysbench.Initialize(); err != nil {
		client.Fatalf("[sysbench] initialize %v error %v", sysbench, err)
	}
	if err := sysbench.Execute(ctx); err != nil {
		client.Fatalf("[sysbench] execution error %v", err)
	}
	select {}
}
