package main

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

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

var (
	defaultPushMetricsInterval = 15 * time.Second
	warmUP                     time.Duration
	dataPath                   string
	loadData                   bool
)

func init() {
	flag.DurationVar(&warmUP, "warm-up", 5*time.Minute, "warm up time")
	flag.BoolVar(&loadData, "load-data", true, "load data for test")
	flag.StringVar(&dataPath, "data-path", "/tpch_scripts", "the path of data and scripts")

	flag.Parse()
}

func main() {
	client.Info("[tpch] start...")

	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("[tpch] Got signal [%s] to exist.", sig)
		cancel()
		os.Exit(0)
	}()

	client.Info("[tpch] start to restore tidb cluster")
	if err := util.RestoreCluster(cli, warmUP, "empty"); err != nil {
		client.Fatalf("[tpch] return with error %v", client.ErrorStack(err))
	}

	client.Info("[tpch] start to run")
	if err := runTPCH(ctx, cli); err != nil {
		client.Fatalf("[tpch] return with error %v", client.ErrorStack(err))
	}
}

func runTPCH(ctx context.Context, cli *client.Client) error {
	tidbAddr := strings.Split(cli.TiDBService(), ":")
	tidbIP, tidbPort := tidbAddr[0], tidbAddr[1]
	port, _ := strconv.Atoi(tidbPort)
	cfg := &TPCHConfig{
		Host:       tidbIP,
		Port:       port,
		ScriptsDir: dataPath,
	}
	tpchSuite := NewTPCHSuite(cfg)

	if loadData {
		client.Info("[tpch] start to load data")
		if err := tpchSuite.loadData(ctx); err != nil {
			return errors.Trace(err)
		}

		client.Infof("[tpch] end load data, sleep %s", warmUP.String())
		time.Sleep(warmUP)
	}

	client.Info("[tpch] start to run test")
	caseResult, err := tpchSuite.run(ctx)
	if err != nil {
		return errors.Trace(err)
	}

	if err := cli.ReportTestResult(caseResult); err != nil {
		client.Errorf("[tpch] report case result %v, failed: %v", caseResult, err)
	}

	return nil
}
