package main

import (
	"flag"
	"fmt"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"syscall"

	"github.com/juju/errors"
	"github.com/ngaut/log"
	"github.com/pingcap/schrodinger/config"
	"github.com/pingcap/schrodinger/manager/api"
	"github.com/pingcap/schrodinger/manager/core"
	"github.com/pingcap/schrodinger/pkg/storage"
	"github.com/pingcap/schrodinger/util"

	_ "github.com/go-sql-driver/mysql"
)

var (
	cfg          *config.Config
	storeConfig  storage.Config
	printVersion bool
	configPath   string
	logLevel     string
)

func init() {
	flag.StringVar(&configPath, "config-file", "", "path to manager config")
	flag.BoolVar(&printVersion, "V", false, "print version")
	flag.StringVar(&logLevel, "log-level", "info", "log level, support info / warning / debug / error / fatal")
}

func loadConfig() {
	cfg = config.GetGlobalConfig()
	if configPath != "" {
		err := cfg.Load(configPath)
		if err != nil {
			log.Fatalf(errors.ErrorStack(err))
		}
	}
}

func setGlobalVars() {
	storeConfig.Driver = cfg.Storage.Driver
	storeConfig.Datasource = cfg.Storage.Datasource
	storeConfig.MaxIdleConns = cfg.Storage.MaxIdleConns
}

func validateConfig() {
	err := util.ValidateListenAddr(cfg.Host)
	if err != nil {
		log.Errorf("verify Listen addr failed %v", err)
		os.Exit(-1)
	}
}

func initLog() {
	log.SetLevelByString(logLevel)
}

func main() {
	flag.Parse()
	if printVersion {
		util.PrintInfo()
		os.Exit(0)
	}

	initLog()
	loadConfig()
	validateConfig()
	setGlobalVars()

	store, err := storage.NewStorage(storeConfig)
	if err != nil {
		log.Fatal(errors.ErrorStack(err))
	}

	mgr, err := core.NewManager(store)
	if err != nil {
		log.Fatalf("can't run manager: %v", err)
	}

	go func() {
		log.Infof("begin to listen %s:%d 😄", cfg.Host, cfg.Port)
		http.ListenAndServe(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port), api.CreateRouter(mgr))
	}()

	go func() {
		log.Info(http.ListenAndServe(":10080", nil))
	}()

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

	sig := <-sc
	log.Infof("Got signal %d to exit.", sig)
}
