package main

import (
	"context"
	"flag"
	"fmt"

	"github.com/tidbcloud/account/internel/svc/token"

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

	"github.com/tidbcloud/account/internel/controllers/acl/access"
	"github.com/tidbcloud/account/internel/svc/apikey"
	"github.com/tidbcloud/account/internel/svc/authn"
	"github.com/tidbcloud/account/internel/svc/dbuser"
	"github.com/tidbcloud/account/internel/svc/rbac"
	"github.com/tidbcloud/account/internel/svc/user"
	"go.uber.org/zap"

	"github.com/tidbcloud/account/central/server"
	"github.com/tidbcloud/account/central/utils"
	"github.com/tidbcloud/account/commons/config"
	"github.com/tidbcloud/account/idl/pbgen/proto/acl"
	grpc_errcode "github.com/tidbcloud/account/pkg/grpc/middleware/errcode"
	"github.com/tidbcloud/account/pkg/version"
	"github.com/tidbcloud/tiinf/monitor/tilog"
)

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

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

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

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

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

	s, err := server.NewServer(configPath, server.GRPCAuthTypeDumb, grpc_errcode.ErrorFormatDefault)
	if err != nil {
		panic(fmt.Sprintf("Failed to create server: %+v", err))
	}

	registerGRPCServices(s)
	go receive.RedisSubscribe(context.Background())
	err = s.Run()
	if err != nil {
		panic(fmt.Sprintf("Run server failed: %+v", err))
	}
}

func registerGRPCServices(s *server.Server) {
	centralService := authn.New()
	dbUserSvc, _ := dbuser.GetDBUserSvc()
	userSvc, _ := user.GetUserSvc()
	tokenSvc, _ := token.GetTokenSvc()
	rbacSvc, _ := rbac.GetRbacUserSvc()
	apiKeySvc, _ := apikey.GetApiKeySvc()
	rbacRoleBindingSvc, _ := rbac.GetRbacRoleBindingSvc()
	acl.RegisterAccessServiceServer(s.TiInf.GrpcServer(), access.NewService(centralService, dbUserSvc, userSvc, tokenSvc, rbacSvc, apiKeySvc, rbacRoleBindingSvc))
}
