/**
 * Pure REST handlers for `/api/sessions/*`.
 *
 * Same shape as projects handlers — see that file's header for the contract.
 *
 * Note: session deletion does not tear down the in-flight spectral stream itself.
 * The Batch 3 dispatcher must call `manager.disposeSessionStream(id)` BEFORE
 * invoking `handleDeleteSession` so the FK cascade doesn't leave a zombie
 * bridge driving events at a row that no longer exists. This matches the
 * ordering the old Hono route used.
 */
import { BadRequestError, NotFoundError } from "./errors.js";
export function handleCreateSession(store, body) {
    if (typeof body.projectId !== "string" || !body.projectId) {
        throw new BadRequestError("projectId (string) is required");
    }
    const project = store.getProject(body.projectId);
    if (!project)
        throw new BadRequestError("Unknown projectId");
    const title = typeof body.title === "string" ? body.title : undefined;
    return store.createSession({ projectId: body.projectId, title });
}
export function handleGetSessionDetail(store, id) {
    const detail = store.getSession(id);
    if (!detail)
        throw new NotFoundError("Session not found");
    return detail;
}
export function handleUpdateSession(store, id, body) {
    if (typeof body.title !== "string") {
        throw new BadRequestError("title (string) is required");
    }
    const updated = store.renameSession(id, body.title);
    if (!updated)
        throw new NotFoundError("Session not found");
    return updated;
}
export function handleDeleteSession(store, id) {
    const deleted = store.deleteSession(id);
    if (!deleted)
        throw new NotFoundError("Session not found");
}
export function handleGetSessionMemoryStatus(store, manager, id) {
    const detail = store.getSession(id);
    if (!detail)
        throw new NotFoundError("Session not found");
    return manager.getSessionMemoryStatus(id);
}
export function handleGetSessionMemoryDetails(store, manager, id) {
    const detail = store.getSession(id);
    if (!detail)
        throw new NotFoundError("Session not found");
    return manager.getSessionMemoryDetails(id);
}
export async function handleCompactSession(store, manager, id) {
    const detail = store.getSession(id);
    if (!detail)
        throw new NotFoundError("Session not found");
    try {
        await manager.compactSession(id);
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        throw new BadRequestError(message);
    }
    return { ok: true };
}
/**
 * Remember & delete: compact the session (which persists observations as
 * project memory via the compaction hook), then delete the session.
 *
 * This gives the user a way to keep a session's reflections as durable
 * cross-session memory even for short sessions that never hit the compaction
 * threshold naturally.
 */
export async function handleRememberAndDeleteSession(store, manager, id) {
    const detail = store.getSession(id);
    if (!detail)
        throw new NotFoundError("Session not found");
    try {
        await manager.compactSession(id);
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        throw new BadRequestError(message);
    }
    return { ok: true };
}
/**
 * Fork a session: create a new session copying all messages from the
 * source, with the `fork_compact_source_id` flag set so the
 * SessionStreamManager compacts after the first assistant turn.
 */
export function handleForkSession(store, id, body) {
    const source = store.getSession(id);
    if (!source)
        throw new NotFoundError("Session not found");
    const title = typeof body.title === "string" ? body.title : undefined;
    return store.forkSession(id, { title });
}
