package server

import (
	"context"
	"errors"
	"fmt"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/config"
	"github.com/tidbcloud/AgentTeam/internal/router"
	"github.com/tidbcloud/AgentTeam/internal/store/workspace"
)

type workspaceAGSWorkspaceChecker interface {
	IsWorkspaceRoutableToGroup(context.Context, string, string) (bool, error)
}

type workspaceAGSWorkspaceResolver interface {
	ResolveWorkspaceRouteTarget(context.Context, string) (workspace.WorkspaceRouteTarget, error)
}

// ConfigureWorkspaceAGSSeam installs the production target-side authority in
// front of the embedded AGS handler. Registration activation, local placement,
// and repository ownership all fail closed before AGS receives the request.
func (server *Server) ConfigureWorkspaceAGSSeam(groupID string, checker workspaceAGSWorkspaceChecker) error {
	if server == nil || checker == nil || strings.TrimSpace(groupID) == "" || server.ags == nil || server.meshxDB == nil {
		return errors.New("configure workspace AGS seam: group, managed workspaces, repository bindings, and AGS are required")
	}
	if err := server.validateWorkspaceAGSSeam(); err != nil {
		return err
	}
	server.handlerMu.Lock()
	defer server.handlerMu.Unlock()
	server.handler = server.readinessGate(router.WorkspaceAGSSeam(
		server.cfg, groupID, checker, newWorkspaceAGSRepositoryAuthority(server.meshxDB), server.ags.Handler(), server.baseHandler,
	))
	return nil
}

// ConfigureStandaloneWorkspaceAGSSeam installs the canonical AGS authority for
// an all-in-one deployment. Placement is resolved per path workspace so this
// compatibility topology does not weaken the split target's fixed-group fence.
func (server *Server) ConfigureStandaloneWorkspaceAGSSeam(resolver workspaceAGSWorkspaceResolver) error {
	if server == nil || resolver == nil || server.ags == nil || server.meshxDB == nil {
		return errors.New("configure standalone workspace AGS seam: workspace placement, repository bindings, and AGS are required")
	}
	if err := server.validateWorkspaceAGSSeam(); err != nil {
		return err
	}
	server.handlerMu.Lock()
	defer server.handlerMu.Unlock()
	server.handler = server.readinessGate(router.StandaloneWorkspaceAGSSeam(
		server.cfg, resolver, newWorkspaceAGSRepositoryAuthority(server.meshxDB), server.ags.Handler(), server.baseHandler,
	))
	return nil
}

func (server *Server) validateWorkspaceAGSSeam() error {
	if !server.cfg.Auth.Enabled || !server.cfg.Auth.TrustedJWTClaims || !server.cfg.Auth.TrustedJWTClaimsProtectedListener {
		return errors.New("configure workspace AGS seam: trusted JWT claims on a protected listener are required")
	}
	if _, err := config.NormalizeSplitTrustedJWTHeader(server.cfg.Auth.Header); err != nil {
		return fmt.Errorf("configure workspace AGS seam: %w", err)
	}
	return nil
}
