package main

import (
	"context"
	"flag"
	"fmt"
	"message-service/api"
	"message-service/commons/config"
	"message-service/commons/database"

	"github.com/gin-gonic/gin"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"github.com/tidbcloud/tiinf/monitor/titracing"
	"github.com/tidbcloud/tiinf/transport/http/tigin"
	"go.uber.org/zap"
)

const (
	componentName     = "message-service-central"
	defaultConfigPath = "/etc/dbaas/config.yaml"
)

// @title message service API
// @version 1.0
// @description This is message service server

// @host 127.0.0.1:8080
// @BasePath /api/v1/message
func main() {
	// parse config parse
	var configPath string
	flag.StringVar(&configPath, "config-path", defaultConfigPath, "DBaaS configuration file path")
	flag.Parse()

	ctx := context.Background()

	// init config
	err := config.InitConfig(configPath)
	if err != nil {
		panic(fmt.Sprintf("Initialize configuration failed, err: %+v", err))
	}

	setup(ctx)

	tilog.Info(ctx, "Connect to database.")
	conf := config.Global()
	// Connect database
	database.Connect(ctx,
		conf.MysqlConf.User,
		conf.MysqlConf.Password,
		conf.MysqlConf.Host,
		conf.MysqlConf.Port,
		conf.MysqlConf.Database,
		conf.MysqlConf.CharSet,
		conf.MysqlConf.TimeZone,
	)

	startup(ctx, conf)
	tilog.Info(ctx, "Startup HTTP Service.")
}

func startup(ctx context.Context, conf *config.CentralConfig) {
	serverConfig := conf.ServerConf

	mEng := tigin.Default()
	mEng.Any("/metrics", prometheusHandler())
	go mEng.Run("0.0.0.0:9090") //nolint:errcheck // no need check error

	httpAddr := fmt.Sprintf(":%s", serverConfig.HttpPort)
	eng := tigin.Default()
	api.RouteCentralAPI(eng)
	tilog.Info(ctx, "serving HTTP Service", zap.String("address", httpAddr))
	err := eng.Run(httpAddr)
	panic(fmt.Sprintf("HTTP Service died %+v", err))
}

func setup(ctx context.Context) {
	// jaeger
	if _, err := titracing.InitJaeger(componentName); err != nil {
		tilog.Error(ctx, "init tiinf jaeger provider failed", zap.Error(err))
		panic(fmt.Sprintf("failed to init tracing, err=%v", err))
	}
}

func prometheusHandler() gin.HandlerFunc {
	h := promhttp.Handler()

	return func(c *gin.Context) {
		h.ServeHTTP(c.Writer, c.Request)
	}
}
