package forwarder

import (
	"net/http"

	"github.com/gin-gonic/gin"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/core/authidentity"
)

// WorkspaceAGSSessionBridge re-authenticates canonical AgentTeam sessions at the
// Workspace target and projects the verified user into the trusted JWT already
// consumed by embedded MeshX/AGS. Repository credentials and anonymous public
// reads bypass this session-only bridge and remain owned by AGS.
func WorkspaceAGSSessionBridge(dependencies Dependencies, next http.Handler) http.Handler {
	if next == nil {
		next = http.NotFoundHandler()
	}
	issuer := newHandlerCore(dependencies)
	sessionRouter := gin.New()
	sessionRouter.Any(
		"/api/v1/workspaces/:workspaceId/ags/*path",
		api.RequireAuthenticatedUser(dependencies.AuthStore),
		api.RequireVerifiedIdentity(dependencies.EmailVerificationRequired),
		api.RequireRouteWorkspace(api.NewOwnedWorkspaceResolver(dependencies.WorkspaceStore, dependencies.ManagedWorkspaces)),
		func(ctx *gin.Context) {
			authenticated, ok := api.AuthenticatedUserFromContext(ctx)
			if !ok {
				api.Error(ctx, http.StatusUnauthorized, "Unauthorized")
				return
			}
			jwt, err := issuer.issueTrustedJWT(ctx, authenticated)
			if err != nil {
				api.Error(ctx, http.StatusInternalServerError, "Failed to prepare upstream identity")
				return
			}
			workspaceID, ok := validatedCurrentWorkspaceID(ctx)
			if !ok {
				api.Error(ctx, http.StatusBadRequest, "No workspace selected")
				return
			}
			request := ctx.Request.Clone(ctx.Request.Context())
			request.Header = cloneHeader(ctx.Request.Header)
			authorization := "Bearer " + jwt
			request.Header.Set("Authorization", authorization)
			request.Header.Set(trustedJWTHeader, authorization)
			request.Header.Set(api.HeaderWorkspaceID, workspaceID)
			next.ServeHTTP(ctx.Writer, request)
			ctx.Abort()
		},
	)
	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		_, status := authidentity.ParseSessionAuthorization(request.Header.Values("Authorization"))
		if status != authidentity.SessionAuthorizationValid {
			next.ServeHTTP(writer, request)
			return
		}
		sessionRouter.ServeHTTP(writer, request)
	})
}
