import { handleHealthRoute, handleRuntimeRoutes, handleStateStatusRoute, handleWorkspaceRuntimeRoute, } from "./runtimeRoutes.js";
import { handleLocalUiPreAuthRoutes, handleLocalUiRoutes, } from "./localUiRoutes.js";
import { handleSecurityContractRoute, handleDebugRevealRoutes, } from "./securityRoutes.js";
import { handleSeedStatusRoute } from "./seedStatus.js";
import { handleSyncStatusRoute } from "./syncStatus.js";
import { handleSyncOptionsRoutes } from "./syncOptionsRoutes.js";
import { handleProjectionRoutes } from "./projectionRoutes.js";
import { handleEvidenceRoute } from "./evidenceRoutes.js";
import { handleCapabilityRoutes } from "./capabilityRoutes.js";
import { handleAggregateRoutes } from "./aggregateRoutes.js";
import { handleReviewDecisionRoute } from "./reviewDecisionRoutes.js";
import { handleRemoteControlCommandAuditRoute, handleRemoteControlConfirmationsRoutes, handleRemoteControlOptionsRoutes, handleRemoteControlPairingClaimRoute, } from "./remoteControlRoutes.js";
import { handleWorkspacePermissionRoutes, handlePermissionRoutes, } from "./permissionRoutes.js";
import { handleProviderAuthRoutes } from "./providerAuthRoutes.js";
import { handleLocalRunIntentMintRoute } from "./localRunIntentMintRoute.js";
import { handleRunIntentReceiptRoutes } from "./runIntentReceiptRoutes.js";
import { handleWorkspaceRunRoutes } from "./workspaceRunRoutes.js";
import { handleRunCancelRoute } from "./runCancelRoute.js";
import { handleRunRetryRoute } from "./runRetryRoute.js";
import { handleForgeRoutes } from "./forgeRoutes.js";
import { handleRepositoryRoutes } from "./repositoryRoutes.js";
function matchesPattern(pattern, pathname) {
    return typeof pattern === "string"
        ? pathname === pattern
        : pattern.test(pathname);
}
/**
 * Pre-auth route table. Order is irrelevant because patterns are mutually
 * exclusive, but it mirrors the historical sequence (health, then the local-UI
 * pre-auth handoff trio) for readability.
 */
export const PRE_AUTH_ROUTES = [
    {
        method: "GET",
        pattern: "/health",
        routeId: "health",
        handler: handleHealthRoute,
    },
    {
        method: "POST",
        pattern: "/local-ui/session",
        routeId: "local-ui.session",
        handler: handleLocalUiPreAuthRoutes,
    },
    {
        method: "POST",
        pattern: "/local-ui/session/renew",
        routeId: "local-ui.session.renew",
        handler: handleLocalUiPreAuthRoutes,
    },
    {
        method: "GET",
        pattern: "/local-ui/authority",
        routeId: "local-ui.authority",
        handler: handleLocalUiPreAuthRoutes,
    },
    {
        method: "POST",
        pattern: "/local-ui/capabilities",
        routeId: "local-ui.capabilities",
        handler: handleLocalUiPreAuthRoutes,
    },
];
const WS = "[^/]+";
/**
 * Authed route table. Scopes mirror the previous `requiredScopeFor` policy
 * exactly; `routeId`s mirror the previous `routeIdFor` mapping. Routes that read
 * bridge state default to `bridge:read`; mutation/manage routes carry their
 * specific scope; legacy bridge-token-only mutation routes carry `null`.
 */
export const AUTHED_ROUTES = [
    // Local-UI session metadata (GET) — bridge:read.
    {
        method: "GET",
        pattern: "/local-ui/session",
        routeId: "local-ui.session",
        scope: "bridge:read",
        handler: handleLocalUiRoutes,
    },
    // Global runtime diagnostics + lifecycle.
    {
        method: "GET",
        pattern: "/runtime/status",
        routeId: "runtime.status",
        scope: "bridge:read",
        handler: handleRuntimeRoutes,
    },
    {
        method: "POST",
        pattern: "/runtime/start",
        routeId: "runtime.start",
        scope: null,
        handler: handleRuntimeRoutes,
    },
    {
        method: "POST",
        pattern: "/runtime/stop",
        routeId: "runtime.stop",
        scope: null,
        handler: handleRuntimeRoutes,
    },
    // Security contract + state diagnostics.
    {
        method: "GET",
        pattern: "/security/contracts",
        routeId: "security.contracts",
        scope: "bridge:read",
        handler: handleSecurityContractRoute,
    },
    {
        method: "GET",
        pattern: "/state/status",
        routeId: "state.status",
        scope: "bridge:read",
        handler: handleStateStatusRoute,
    },
    {
        method: "GET",
        pattern: "/state/seed-status",
        routeId: "state.seed-status",
        scope: "bridge:read",
        handler: handleSeedStatusRoute,
    },
    {
        method: "GET",
        pattern: "/state/sync-status",
        routeId: "state.sync-status",
        scope: "bridge:read",
        handler: handleSyncStatusRoute,
    },
    // Sync options — read/write per-domain depth settings.
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/sync/options$`),
        routeId: "workspace.sync.options",
        scope: "bridge:read",
        handler: handleSyncOptionsRoutes,
    },
    {
        method: "PUT",
        pattern: new RegExp(`^/workspaces/${WS}/sync/options$`),
        routeId: "workspace.sync.options",
        scope: "bridge:read",
        handler: handleSyncOptionsRoutes,
    },
    // Layer 3 Remote Control — policy CRUD, parked-confirmation list/resolve,
    // and the outbound device-pairing claim. Scope 'remote:control'.
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/remote-control/options$`),
        routeId: "workspace.remote-control.options",
        scope: "remote:control",
        handler: handleRemoteControlOptionsRoutes,
    },
    {
        method: "PUT",
        pattern: new RegExp(`^/workspaces/${WS}/remote-control/options$`),
        routeId: "workspace.remote-control.options",
        scope: "remote:control",
        handler: handleRemoteControlOptionsRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/remote-control/confirmations$`),
        routeId: "workspace.remote-control.confirmations",
        scope: "remote:control",
        handler: handleRemoteControlConfirmationsRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/remote-control/confirmations/[^/]+/resolve$`),
        routeId: "workspace.remote-control.confirmations.resolve",
        scope: "remote:control",
        handler: handleRemoteControlConfirmationsRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/remote-control/command-audit$`),
        routeId: "workspace.remote-control.command-audit",
        scope: "remote:control",
        handler: handleRemoteControlCommandAuditRoute,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/remote-control/pairings/claim$`),
        routeId: "workspace.remote-control.pairings.claim",
        scope: "remote:control",
        handler: handleRemoteControlPairingClaimRoute,
    },
    // Workspace capability projections.
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/capabilities/repositories$`),
        routeId: "workspace.capabilities.repositories",
        scope: "bridge:read",
        handler: handleCapabilityRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/capabilities/onboarding$`),
        routeId: "workspace.capabilities.onboarding",
        scope: "bridge:read",
        handler: handleCapabilityRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/capabilities/settings$`),
        routeId: "workspace.capabilities.settings",
        scope: "bridge:read",
        handler: handleCapabilityRoutes,
    },
    // Aggregate + review/proof/metrics/overview projections.
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/capabilities/metrics$`),
        routeId: "workspace.capabilities.metrics",
        scope: "bridge:read",
        handler: handleAggregateRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/capabilities/overview$`),
        routeId: "workspace.capabilities.overview",
        scope: "bridge:read",
        handler: handleAggregateRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/capabilities/overview-dashboard$`),
        routeId: "workspace.capabilities.overview-dashboard",
        scope: "bridge:read",
        handler: handleAggregateRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/review-queue$`),
        routeId: "workspace.review-queue",
        scope: "bridge:read",
        handler: handleAggregateRoutes,
    },
    // Review decision mutation (review-item-scoped) — least-privilege
    // bridge:review scope. Records the terminal local-first core-loop step.
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/review-queue/${WS}/decision$`),
        routeId: "workspace.review-queue.decision",
        scope: "bridge:review",
        handler: handleReviewDecisionRoute,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/proof-cards$`),
        routeId: "workspace.proof-cards",
        scope: "bridge:read",
        handler: handleAggregateRoutes,
    },
    // Run evidence (loopback). Returns bounded per-file patch content alongside
    // changed-file metadata, validations, and warnings.
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/runs/${WS}/evidence$`),
        routeId: "workspace.runs.evidence",
        scope: "bridge:read",
        handler: handleEvidenceRoute,
    },
    // Run + audit projections.
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/projections/runs$`),
        routeId: "workspace.projections.runs",
        scope: "bridge:read",
        handler: handleProjectionRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/projections/runs/${WS}$`),
        routeId: "workspace.projections.runs.detail",
        scope: "bridge:read",
        handler: handleProjectionRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/projections/audit$`),
        routeId: "workspace.projections.audit",
        scope: "bridge:read",
        handler: handleProjectionRoutes,
    },
    // Workspace runtime diagnostics.
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/runtime/status$`),
        routeId: "workspace.runtime.status",
        scope: "bridge:read",
        handler: handleWorkspaceRuntimeRoute,
    },
    // Debug reveal (debug:reveal scope).
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/debug-reveal/status$`),
        routeId: "workspace.debug-reveal.status",
        scope: "debug:reveal",
        handler: handleDebugRevealRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/debug-reveal/sessions$`),
        routeId: "workspace.debug-reveal.sessions",
        scope: "debug:reveal",
        handler: handleDebugRevealRoutes,
    },
    {
        method: "DELETE",
        pattern: new RegExp(`^/workspaces/${WS}/debug-reveal/sessions/${WS}$`),
        routeId: "workspace.debug-reveal.sessions.revoke",
        scope: "debug:reveal",
        handler: handleDebugRevealRoutes,
    },
    // Permission activity + decisions (workspace-scoped).
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/permissions/activity$`),
        routeId: "workspace.permissions.activity",
        scope: "bridge:read",
        handler: handleWorkspacePermissionRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/permissions/decisions$`),
        routeId: "workspace.permissions.decisions",
        scope: "bridge:read",
        handler: handleWorkspacePermissionRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/permissions/decisions/${WS}/revoke$`),
        routeId: "workspace.permissions.decisions.revoke",
        scope: "permissions:manage",
        handler: handleWorkspacePermissionRoutes,
    },
    // Provider auth (read/write scopes resolved by method).
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/provider-profiles$`),
        routeId: "workspace.provider-profiles",
        scope: "provider-auth:read",
        handler: handleProviderAuthRoutes,
    },
    // The list path historically resolved PUT/DELETE to provider-auth:write even
    // though only GET is served; these entries preserve that exact scope boundary
    // (the handler serves no PUT/DELETE list route, so dispatch falls through to a
    // 404 just as the previous sequential router did).
    {
        method: "PUT",
        pattern: new RegExp(`^/workspaces/${WS}/provider-profiles$`),
        routeId: "workspace.provider-profiles",
        scope: "provider-auth:write",
        handler: handleProviderAuthRoutes,
    },
    {
        method: "DELETE",
        pattern: new RegExp(`^/workspaces/${WS}/provider-profiles$`),
        routeId: "workspace.provider-profiles",
        scope: "provider-auth:write",
        handler: handleProviderAuthRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/provider-profiles/${WS}/credential$`),
        routeId: "workspace.provider-profiles.credential",
        scope: "provider-auth:read",
        handler: handleProviderAuthRoutes,
    },
    {
        method: "PUT",
        pattern: new RegExp(`^/workspaces/${WS}/provider-profiles/${WS}/credential$`),
        routeId: "workspace.provider-profiles.credential",
        scope: "provider-auth:write",
        handler: handleProviderAuthRoutes,
    },
    {
        method: "DELETE",
        pattern: new RegExp(`^/workspaces/${WS}/provider-profiles/${WS}/credential$`),
        routeId: "workspace.provider-profiles.credential",
        scope: "provider-auth:write",
        handler: handleProviderAuthRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/providers/openai/credentials/api-key$`),
        routeId: "workspace.providers.openai.credentials.api-key",
        scope: "provider-auth:read",
        handler: handleProviderAuthRoutes,
    },
    {
        method: "PUT",
        pattern: new RegExp(`^/workspaces/${WS}/providers/openai/credentials/api-key$`),
        routeId: "workspace.providers.openai.credentials.api-key",
        scope: "provider-auth:write",
        handler: handleProviderAuthRoutes,
    },
    {
        method: "DELETE",
        pattern: new RegExp(`^/workspaces/${WS}/providers/openai/credentials/api-key$`),
        routeId: "workspace.providers.openai.credentials.api-key",
        scope: "provider-auth:write",
        handler: handleProviderAuthRoutes,
    },
    // Repository linking + locate/clone (local-first working copies).
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/repositories$`),
        routeId: "workspace.repositories",
        scope: "repository:read",
        handler: handleRepositoryRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/repositories$`),
        routeId: "workspace.repositories.link",
        scope: "repository:write",
        handler: handleRepositoryRoutes,
    },
    {
        method: "DELETE",
        pattern: new RegExp(`^/workspaces/${WS}/repositories/${WS}$`),
        routeId: "workspace.repositories.unlink",
        scope: "repository:write",
        handler: handleRepositoryRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/repositories/${WS}/locate$`),
        routeId: "workspace.repositories.locate",
        scope: "repository:write",
        handler: handleRepositoryRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/repositories/${WS}/clone$`),
        routeId: "workspace.repositories.clone",
        scope: "repository:write",
        handler: handleRepositoryRoutes,
    },
    // Forge — hybrid local GitHub-write (D085).
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/forge/github/status$`),
        routeId: "workspace.forge.github.status",
        scope: "forge:read",
        handler: handleForgeRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/workspaces/${WS}/forge/github/oauth-url$`),
        routeId: "workspace.forge.github.oauth-url",
        scope: "forge:read",
        handler: handleForgeRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/forge/github/connect$`),
        routeId: "workspace.forge.github.connect",
        scope: "forge:write",
        handler: handleForgeRoutes,
    },
    {
        method: "DELETE",
        pattern: new RegExp(`^/workspaces/${WS}/forge/github/connect$`),
        routeId: "workspace.forge.github.disconnect",
        scope: "forge:write",
        handler: handleForgeRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/forge/evidence$`),
        routeId: "workspace.forge.evidence",
        scope: "forge:write",
        handler: handleForgeRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/forge/proof-draft$`),
        routeId: "workspace.forge.proof-draft",
        scope: "forge:write",
        handler: handleForgeRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/forge/draft-pr$`),
        routeId: "workspace.forge.draft-pr",
        scope: "forge:write",
        handler: handleForgeRoutes,
    },
    // Local run-intent mint (dev/test self-mint) — run-intents:create.
    {
        method: "POST",
        pattern: "/local-ui/run-intent-receipts/mint",
        routeId: "local-ui.run-intent-receipts.mint",
        scope: "run-intents:create",
        handler: handleLocalRunIntentMintRoute,
    },
    // Intent-bound receipt run + prompt routes.
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/run-intent-receipts/runs$`),
        routeId: "workspace.run-intent-receipts.runs",
        scope: "run-intents:create",
        handler: handleRunIntentReceiptRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/runs/${WS}/run-intent-receipts/prompt$`),
        routeId: "runs.run-intent-receipts.prompt",
        scope: "run-intents:prompt",
        handler: handleRunIntentReceiptRoutes,
    },
    // Legacy bridge-token-only run + prompt mutation routes (null scope).
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/runs$`),
        routeId: "workspace.runs",
        scope: "runs:write",
        handler: handleWorkspaceRunRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/runs/${WS}/prompt$`),
        routeId: "runs.prompt",
        scope: "runs:write",
        handler: handleWorkspaceRunRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/runs/${WS}/proof-evidence$`),
        routeId: "runs.proof-evidence",
        scope: "runs:write",
        handler: handleWorkspaceRunRoutes,
    },
    {
        method: "GET",
        pattern: new RegExp(`^/runs/${WS}/events$`),
        routeId: "runs.events",
        scope: "bridge:read",
        handler: handleWorkspaceRunRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/workspaces/${WS}/runs/${WS}/cancel$`),
        routeId: "workspace.runs.cancel",
        scope: "runs:cancel",
        handler: handleRunCancelRoute,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/runs/${WS}/retry$`),
        routeId: "runs.retry",
        scope: "runs:retry",
        handler: handleRunRetryRoute,
    },
    // Global permission requests + reply + evaluate.
    {
        method: "GET",
        pattern: "/permissions/requests",
        routeId: "permissions.requests",
        scope: "bridge:read",
        handler: handlePermissionRoutes,
    },
    {
        method: "POST",
        pattern: new RegExp(`^/permissions/requests/${WS}/reply$`),
        routeId: "permissions.requests.reply",
        scope: "permissions:reply",
        handler: handlePermissionRoutes,
    },
    {
        method: "POST",
        pattern: "/permissions/evaluate",
        routeId: "permissions.evaluate",
        scope: "permissions:evaluate",
        handler: handlePermissionRoutes,
    },
];
/**
 * Resolves the pre-auth entry for a request, if any. Pre-auth routes are tried
 * before the central authentication step.
 */
export function matchPreAuthRoute(method, pathname) {
    return PRE_AUTH_ROUTES.find((entry) => entry.method === method && matchesPattern(entry.pattern, pathname));
}
/**
 * Resolves the authed entry for a request, if any.
 */
export function matchAuthedRoute(method, pathname) {
    return AUTHED_ROUTES.find((entry) => entry.method === method && matchesPattern(entry.pattern, pathname));
}
/**
 * Default scope applied to requests that match no authed table entry. Preserves
 * the historical behaviour: any GET (known or unknown path) is authenticated at
 * the `bridge:read` floor before the server reveals whether the route exists,
 * while non-GET unmatched requests carry no scope and are reachable only by the
 * bridge-token authority (then fall through to a 404).
 */
export function fallbackScopeForUnmatchedRoute(method) {
    return method === "GET" ? "bridge:read" : null;
}
/**
 * Resolves the required scope for a request: the matched entry's declared scope,
 * or the documented fallback when no entry matches. Returns `null` for
 * bridge-token-only routes (the authenticator treats `null` as "no local-UI
 * scope required").
 */
export function requiredScopeFor(method, pathname) {
    const entry = matchAuthedRoute(method, pathname);
    return entry ? entry.scope : fallbackScopeForUnmatchedRoute(method);
}
/**
 * Resolves the stable diagnostic route id for a request, or `undefined` when no
 * entry matches (an unknown route has no id, exactly as before).
 */
export function routeIdFor(method, pathname) {
    return matchAuthedRoute(method, pathname)?.routeId;
}
