package gateway

import (
	"net/http"
	"net/url"
	"strings"

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

// This file is the complete Edge compatibility owner for Desktop releases
// whose embedded Web bundle still calls unscoped MeshX and LLM URLs. Those
// releases already send the selected server workspace in
// X-AgentTeam-Route-Workspace-Id; the Edge validates that discriminator and rewrites
// the request to the canonical Workspace Server URL without changing method,
// body, query, escaped suffix, authentication, or cancellation.
//
// Keep this adapter out of Workspace Server route registration: a direct old
// URL must continue to return 404. Do not expand it to infer a workspace from a
// user session, X-Workspace-Id alone, or a default owner group.
//
// Removal condition: after supported Desktop releases all construct canonical
// /api/v1/workspaces/:workspaceId URLs and Edge observations show no legacy
// family traffic for the agreed compatibility window, delete this file, the
// legacyDesktopWorkspaceData decision field/call site, its focused tests, and
// the matching Desktop header-injection inventory in desktop/internal/api.

func isLegacyDesktopWorkspaceRoute(path string) bool {
	if pathMatchesPrefix(path, "/api/llm") ||
		path == "/api/v1/roles:from-agent" ||
		path == "/api/v1/repository-owners" ||
		path == "/api/v1/repository-names/available" ||
		path == "/api/v1/agent-thread/session-channel" {
		return true
	}
	return hasAnyPathPrefix(path,
		"/api/v1/kb", "/api/v1/memory", "/api/v1/skills", "/api/v1/roles",
		"/api/v1/repository-access-tokens", "/api/v1/internal/repository-access-tokens",
		"/api/v1/personal-access-tokens", "/api/v1/automations", "/api/v1/mcp",
		"/api/v1/repositories",
	)
}

func prepareLegacyDesktopWorkspaceRequest(writer http.ResponseWriter, request *http.Request) bool {
	if request == nil || request.URL == nil {
		return false
	}
	queryWorkspaceID, ok := uniqueLegacyDesktopWorkspaceQuery(request.URL.Query())
	if !ok {
		http.Error(writer, "conflicting route workspace identity", http.StatusBadRequest)
		return false
	}
	routeWorkspaceID := strings.TrimSpace(request.Header.Get(api.HeaderRouteWorkspaceID))
	if routeWorkspaceID == "" {
		http.Error(writer, api.HeaderRouteWorkspaceID+" is required", http.StatusBadRequest)
		return false
	}
	if !api.IsValidRouteWorkspaceID(routeWorkspaceID) {
		http.Error(writer, "invalid route workspace identity", http.StatusBadRequest)
		return false
	}
	if queryWorkspaceID != "" {
		if !api.IsValidRouteWorkspaceID(queryWorkspaceID) {
			http.Error(writer, "invalid route workspace identity", http.StatusBadRequest)
			return false
		}
		if queryWorkspaceID != routeWorkspaceID {
			http.Error(writer, "conflicting route workspace identity", http.StatusBadRequest)
			return false
		}
	}
	return rewriteLegacyDesktopWorkspacePath(request, routeWorkspaceID)
}

func uniqueLegacyDesktopWorkspaceQuery(query url.Values) (string, bool) {
	workspaceID := ""
	for _, key := range []string{"workspaceId", "workspace_id"} {
		for _, value := range query[key] {
			value = strings.TrimSpace(value)
			if value == "" {
				continue
			}
			if workspaceID != "" && workspaceID != value {
				return "", false
			}
			workspaceID = value
		}
	}
	return workspaceID, true
}

func rewriteLegacyDesktopWorkspacePath(request *http.Request, workspaceID string) bool {
	path := requestPath(request)
	switch {
	case pathMatchesPrefix(path, "/api/v1"):
		return rewriteRequestPathPrefix(request, "/api/v1", "/api/v1/workspaces/"+workspaceID)
	case pathMatchesPrefix(path, "/api/llm"):
		return rewriteRequestPathPrefix(request, "/api/llm", "/api/v1/workspaces/"+workspaceID+"/llm")
	default:
		return false
	}
}
