package activities

import (
	"sync"

	"github.com/gin-gonic/gin"
	"go.uber.org/fx"

	"github.com/pingcap-inc/clinic/pkg/activityhub_client"
	"github.com/pingcap-inc/clinic/pkg/config"
	"github.com/pingcap-inc/clinic/pkg/rbac"
	"github.com/pingcap-inc/clinic/pkg/resource_limit"
	"github.com/pingcap-inc/clinic/pkg/upload_file/decrypt"
)

type EventManagerService struct {
	cfg  *config.Config
	rbac *rbac.AuthCasbin
	// quotalimiter *resource_limit.QuotaLimiter
	quotalimiter resource_limit.IQuotaLimiter
	// sessionManager *session.SessionManager
	hubClient *activityhub_client.ActivityHubClient
	searcher  activitySearcher
	owns      clusterOwnershipChecker

	gitOpsMonitor *gitOpsMonitor
	once          sync.Once
}

func NewEventManagerService(cfg *config.Config, decrypt *decrypt.Decrypt, rbac *rbac.AuthCasbin, quotalimit resource_limit.IQuotaLimiter) *EventManagerService {
	var activityHubAddr, activityHubSource, activityHubKey string
	if cfg != nil && cfg.ActivityManagerConfig != nil {
		activityHubAddr = cfg.ActivityManagerConfig.ActivityHubAddr
		activityHubSource = cfg.ActivityManagerConfig.ActivityHubSource
		activityHubKey = cfg.ActivityManagerConfig.ActivityHubKey
	}
	hubClient := activityhub_client.NewClient(activityHubAddr, activityHubSource, activityHubKey)
	return &EventManagerService{
		cfg:          cfg,
		rbac:         rbac,
		quotalimiter: quotalimit,
		hubClient:    hubClient,
		searcher:     hubClient,
		owns:         ownsClusterInDBAASOrg,
	}
}

func registerRouter(r *gin.RouterGroup, s *EventManagerService) {
	router := r.Group("/activityhub")

	router.GET("/applications/:application_id/targets/:target_id/activities", s.QueryActivities)
	router.GET("/applications/:application_id/targets/:target_id/activities/:activity_id", s.GetActivitiy)
	router.GET("/applications/:application_id/targets/:target_id/activitygroups", s.QueryActivityGroups)
	router.GET("/applications/:application_id/targets/:target_id/activitygroups/:context_id", s.GetActivityGroup)
	router.POST("/applications/:application_id/targets/:target_id/contexts/:context_id", s.PostGitOpsActivity)
}

func registerInternalRouter(r *gin.RouterGroup, s *EventManagerService) {
	internal := r.Group("/internal/data-proxy/v1")
	internal.GET("/orgs/:orgId/clusters/:clusterId/activities", s.QueryInternalActivities)
}

var Module = fx.Options(
	fx.Provide(NewEventManagerService),
	fx.Invoke(registerRouter))

// InternalModule exposes only the Clinic-owned APIs consumed by Data Proxy.
var InternalModule = fx.Options(
	fx.Provide(NewEventManagerService),
	fx.Invoke(registerInternalRouter),
)
