package main

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

	"strings"

	"github.com/pingcap/log"
	"github.com/tidbcloud/ffs/config"
	"github.com/tidbcloud/ffs/pkg/v1/proto"
	"github.com/tidbcloud/ffs/universe"
	"github.com/tidbcloud/ffs/util/logutil"
	"github.com/tidbcloud/ffs/util/netutil"
	"go.etcd.io/etcd/clientv3"
	"google.golang.org/grpc"
)

var (
	endpoints     = flag.String("endpoints", "localhost:2379,localhost:12379,localhost:22379", "The etcd endpoints in the format of host:port,host:port")
	serverAddr    = flag.String("addr", "localhost:9091", "The server address in the format of host:port")
	advertiseAddr = flag.String("advertise-addr", "", "advertise address")
	statusAddr    = flag.String("status-addr", "localhost:6061", "status address")
	logLevel      = flag.String("log-level", "info", "log level: info, debug, warn, error, fatal")
)

var (
	gitHash = "None"
)

func main() {
	flag.Parse()
	logutil.SetLevel(*logLevel)
	log.S().Infof("gitHash: %s", gitHash)

	storeClient, err := clientv3.New(clientv3.Config{
		Endpoints:   strings.Split(*endpoints, ","),
		DialTimeout: 5 * time.Second,
	})
	if err != nil {
		log.S().Fatalf("failed to new etcd client: %v", err)
	}

	port := netutil.ParsePort(*serverAddr)
	if len(port) == 0 {
		log.S().Fatalf("failed to parse port: %v", *serverAddr)
	}
	lis, err := net.Listen("tcp", ":"+port)
	if err != nil {
		log.S().Fatalf("failed to listen: %v", err)
	}
	log.S().Infof("server listening at %v", lis.Addr())

	s := grpc.NewServer(
		grpc.MaxRecvMsgSize(config.GrpcMaxMsgSize),
		grpc.MaxSendMsgSize(config.GrpcMaxMsgSize),
	)

	if len(*advertiseAddr) == 0 {
		*advertiseAddr = netutil.GetLocalIP() + ":" + port
	}
	universeSvr := universe.NewUniverseServer(*advertiseAddr, storeClient)
	proto.RegisterUniverseServiceServer(s, universeSvr)

	go http.ListenAndServe(*statusAddr, nil)
	go s.Serve(lis)
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT)
	sig := <-sigCh
	log.S().Infof("got signal [%s] to exit.", sig)
	universeSvr.Stop()
}
