package main

import (
	"context"
	"flag"
	"fmt"
	_ "net/http/pprof"

	"github.com/tidbcloud/account/internel/controllers/provider/inner"
	"github.com/tidbcloud/account/internel/svc/rbac"
	"github.com/tidbcloud/account/internel/svc/user/session"

	"github.com/tidbcloud/account/central/events/receive"

	"github.com/tidbcloud/account/commons/database"
	"github.com/tidbcloud/account/commons/eventbus"
	"github.com/tidbcloud/account/commons/redis"
	"github.com/tidbcloud/account/internel/controllers/launcher"
	"github.com/tidbcloud/account/internel/controllers/provider/account"

	"github.com/tidbcloud/account/central/utils"
	"github.com/tidbcloud/account/commons/config"
	"github.com/tidbcloud/account/pkg/version"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
)

const (
	componentName     = "account-provider"
	defaultConfigPath = "/etc/dbaas/config.yaml"
)

func initialize(configPath string) *config.CentralConfig {
	ctx := context.Background()

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

	_, err = redis.InitRedisClient()
	if err != nil {
		panic(fmt.Sprintf("failed to create redis client: %s", err))
	}
	mysqlConfig := config.Global().MysqlConfig
	_, err = database.Initialize(ctx, mysqlConfig)
	if err != nil {
		panic(fmt.Sprintf("initialize global database connection failed: %s", err))
	}

	err = utils.SetupLoggerAndSentry()
	if err != nil {
		panic(fmt.Sprintf("Initialize logger and sentry failed: %+v", err))
	}

	tilog.Info(ctx, fmt.Sprintf("starting %s service", componentName),
		zap.String("gitHash", version.GitHash),
		zap.String("logLevel", config.Global().ServerConfig.LogLevel))

	return centralConfig
}

func main() {
	var configPath string
	flag.StringVar(&configPath, "config-path", defaultConfigPath, "DBaaS configuration file path")
	flag.Parse()

	_ = initialize(configPath)

	rbac.TimingLoadRbacResource()

	// Initialize the service
	controller := account.NewAccountController()

	launcher := launcher.New(configPath)
	launcher.Init()
	launcher.RegisterProvider(controller)
	// register http router
	engine := launcher.GinEngine()
	inner.RegisterApiKeyRouter(engine)
	inner.RegisterUserRouter(engine)

	if !config.IsLocalEnv() {

		err := eventbus.Get().Run()
		tilog.Info(context.Background(), "eventbus.Run result="+fmt.Sprintf("%t", err == nil))
		if err != nil {
			tilog.Fatal(context.Background(), "Initialize event bus handler failed", zap.Error(err))
		}
		go receive.RedisSubscribe(context.Background())
		go session.SubscribeSessionInvalidation(context.Background())
	}
	err := launcher.Serve()
	if err != nil {
		panic(err)
	}

}
