package container

// GlobalContainer is the global container for all services and controllers.
// It should be initialized in entry point.
// It is a simple implementation of Dependency Injection.

import (
	"github.com/tidbcloud/account/idl/pbgen/proto/account"
	"github.com/tidbcloud/auth-server/commons/grpc"
	oauth2_controller "github.com/tidbcloud/auth-server/internal/controller/oauth2"
	provider_controller "github.com/tidbcloud/auth-server/internal/controller/provider"
	oauth2_service "github.com/tidbcloud/auth-server/internal/service/oauth2"
	"gorm.io/gorm"
)

var globalContainer *GlobalContainer

type GlobalContainer struct {
	DB *gorm.DB

	// HTTP Controller
	Oauth2Controller oauth2_controller.Oauth2Controller

	// GRPC Controller
	ProviderController provider_controller.ProviderController

	// Service
	Oauth2Service oauth2_service.Oauth2Service

	// Repository

	// External Service
	AccountProviderClient account.AccountAPIServiceClient
}

func (c *GlobalContainer) initExternalService() {
	c.AccountProviderClient = grpc.GetAccountProviderSvcClient()
}

func (c *GlobalContainer) initRepository() {
}

func (c *GlobalContainer) initService() {
	c.Oauth2Service = oauth2_service.NewOauth2Service(c.DB, c.AccountProviderClient)
}

func (c *GlobalContainer) initHttpController() {
	c.Oauth2Controller = oauth2_controller.NewOauth2Controller(c.Oauth2Service)
}

func (c *GlobalContainer) initGrpcController() {
	c.ProviderController = provider_controller.NewProviderContoller(c.Oauth2Service)
}

func Global() *GlobalContainer {
	return globalContainer
}

func InitGlobalContainer(db *gorm.DB) {
	globalContainer = &GlobalContainer{
		DB: db,
	}
	globalContainer.initExternalService()
	globalContainer.initRepository()
	globalContainer.initService()
	globalContainer.initGrpcController()
	globalContainer.initHttpController()
}
