/**
 * Path C cwd redirect (upstream-only mechanism).
 *
 * Replaces the fork-local `SessionWorkspaceApi`
 * (`openclaw/plugin-sdk/session-workspace`), which does NOT exist in upstream
 * OpenClaw. Instead of writing a fork-only `workspace.path` override, this
 * writes the upstream-honored spawn-lineage fields onto the session entry.
 * For each agent run OpenClaw resolves (see `gateway/server-methods/agent.ts`,
 * gated on `spawnedBy` being truthy):
 *   - the process working directory `cwd`  ← `sessionEntry.spawnedCwd`
 *     (`resolveSessionRuntimeCwd`) — this is what bash/exec tools run in;
 *   - the agent `workspaceDir`             ← `sessionEntry.spawnedWorkspaceDir`
 *     (`resolveIngressWorkspaceOverrideForSpawnedRun`).
 * So to land the agent INSIDE the FUSE mount we must set BOTH `spawnedCwd` and
 * `spawnedWorkspaceDir` to the mount path — `spawnedWorkspaceDir` alone leaves
 * the real cwd untouched.
 *
 * Exposes the same `{ set, clear }` shape the rest of the plugin already wires,
 * so gateway-methods and the auto-mount hook are unchanged.
 *
 * - `set(key, { path })` enables the redirect: `spawnedCwd = spawnedWorkspaceDir
 *   = path`, `spawnedBy = pluginId`.
 * - `clear(key)` disables it by unsetting `spawnedBy`. `spawnedCwd` /
 *   `spawnedWorkspaceDir` are left intact on purpose — upstream treats them as
 *   write-once and the resolvers ignore them whenever `spawnedBy` is falsy.
 *
 * NOTE (pending live spike): writing these fields directly to the session store
 * bypasses the gateway `sessions.patch` validation that restricts the spawn
 * fields to `subagent:*` / `acp:*` keys, so this works for the existing
 * `main:*` / `agent:*` key forms. The spike must confirm that setting
 * `spawnedBy` on such sessions has no unwanted side effects (e.g. session
 * visibility/grouping); if it does, move SecAFS conversations onto `acp:*`
 * sessions driven by the standalone frontend.
 */
export interface SpawnedWorkspaceStore {
  patch(key: string, patch: Record<string, unknown>): Promise<void>;
}

export interface SpawnedWorkspaceRedirect {
  set(key: string, spec: { path: string }): Promise<void>;
  clear(key: string): Promise<void>;
}

export function createSpawnedWorkspaceRedirect(
  store: SpawnedWorkspaceStore,
  pluginId: string,
): SpawnedWorkspaceRedirect {
  return {
    async set(key, spec) {
      await store.patch(key, {
        spawnedCwd: spec.path,
        spawnedWorkspaceDir: spec.path,
        spawnedBy: pluginId,
      });
    },
    async clear(key) {
      await store.patch(key, { spawnedBy: undefined });
    },
  };
}