package main

import (
	"flag"
	"fmt"
	"math/rand"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"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", "test", "database name")
	pw          = flag.String("pw", "", "database password")
	testPath    = flag.String("test-path", "./sqllogictest", "test data path")
	concurrency = flag.Int("concurrency", 200, "concurrency")
	parallel    = flag.Int("parallel", 8, "parallel count")
	skipError   = flag.Bool("skip-error", false, "skip error")
	runMode     = flag.String("run-mode", "online", "case mode, support values: online / dev, default value: online")
	caseUrl     = flag.String("case-url", "", "case url")
)

func main() {
	// Initialize the default random number source.
	client.Info("[sqllogic] start...")
	rand.Seed(time.Now().UTC().UnixNano())

	flag.Parse()

	ctx, cancel := context.WithCancel(context.Background())
	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("[sqllogic] Invalid mode: %v,support values: online / dev", mode)
		}
		client.Info("Mode:", clientMode)
		return clientMode
	}(*runMode))

	sc := make(chan os.Signal, 1)
	signal.Notify(sc,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT)

	go func() {
		sig := <-sc
		client.Infof("[sqllogic] Got signal [%s] to exist.", sig)
		cancel()
		os.Exit(0)
	}()

	dbAddr := cli.TiDBService()
	dbDSN := fmt.Sprintf("root:%s@tcp(%s)/%s", *pw, dbAddr, *dbName)
	db, err := util.OpenDB(dbDSN, *concurrency)
	if err != nil {
		client.Infof("[sqllogic] OpenDB error %v", err)
	}

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

	cfg := &SqllogicTestCaseConfig{
		TestPath:  *testPath,
		SkipError: *skipError,
		Parallel:  *parallel,
		DBName:    *dbName,
		Host:      dbAddr,
		User:      "root",
		Password:  *pw,
	}
	sqllogic := NewSqllogictest(cfg)
	err = sqllogic.Initialize(ctx, db)
	if err != nil {
		client.Fatalf("[sqllogic] initialize %s error %v", sqllogic, err)
	}

	err = sqllogic.Execute(ctx, db)
	if err != nil {
		client.Infof("[sqllogic] bank execution error %v", err)
	}
}

func getCaseUrl() string {
	if *caseUrl == "" {
		return "http://fileserver.pingcap.net/download/builds/pingcap/case-data/sqllogic/sqllogictest_case.tar.gz"
	}

	return *caseUrl
}
