package router

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"

	"github.com/tidbcloud/AgentTeam/internal/api/extension"
	"github.com/tidbcloud/AgentTeam/internal/extension/registry"
)

// ExtensionDependencies holds the ProfileExtension runtime collaborators.
// The Catalog is projected from the immutable Registry; Auth reuses the Agent
// Runtime principal authenticator wired on Dependencies.Agent.
type ExtensionDependencies struct {
	Registry *registry.Registry
	Access   extension.AuthorizationSource
	Snapshot extension.CatalogSnapshotSource
	Invoker  extension.InvocationService
}

// validateExtensionDependencies verifies the ProfileExtension hard
// dependencies: the Agent Runtime principal authenticator, immutable Registry,
// and authoritative invocation service.
func (dependencies Dependencies) validateExtensionDependencies(missing *[]string) {
	if dependencies.Agent.Auth == nil {
		*missing = append(*missing, "Agent.Auth")
	}
	if dependencies.Extension.Registry == nil {
		*missing = append(*missing, "Extension.Registry")
	}
	if dependencies.Extension.Invoker == nil {
		*missing = append(*missing, "Extension.Invoker")
	}
}

// profileServesBrowserWeb is the closed allowlist of profiles permitted to
// serve the Web SPA or delegate unmatched AGS Smart-HTTP paths. Extension and
// unknown profiles are API-only and fail closed at NoRoute.
func profileServesBrowserWeb(profile Profile) bool {
	switch profile {
	case ProfileAll, ProfileCentral, ProfileWorkspace:
		return true
	default:
		return false
	}
}

func newNoRouteHandler(profile Profile, web WebDependencies) gin.HandlerFunc {
	if !profileServesBrowserWeb(profile) || !web.ServeWeb {
		return jsonNotFound
	}
	server, err := newWebDistServer(web.DistDir)
	if err != nil {
		return func(ctx *gin.Context) {
			ctx.JSON(http.StatusInternalServerError, gin.H{
				"error": fmt.Sprintf("serve web dist: %v", err),
			})
		}
	}
	return server.Serve
}

// registerExtensionRoutes mounts the two Agent-visible Extension runtime
// routes behind the existing Agent Runtime principal authenticator.
func registerExtensionRoutes(router *gin.Engine, dependencies Dependencies) {
	extension.RegisterRoutes(router, extension.Dependencies{
		Logger:   dependencies.Logger,
		Auth:     dependencies.Agent.Auth,
		Catalog:  dependencies.Extension.Registry,
		Access:   dependencies.Extension.Access,
		Snapshot: dependencies.Extension.Snapshot,
		Invoker:  dependencies.Extension.Invoker,
	})
}
