/**
 * Per-session control channel for an in-flight agent turn.
 *
 * A tool-call loop (agent-loop.ts) can otherwise run unattended for up to
 * MAX_ITERATIONS with no way for the user to intervene — which is exactly
 * how a doomed task melts an instance. This gives two levers, both scoped
 * to a CURRENTLY RUNNING turn:
 *   • abort — break the loop cleanly at the next iteration boundary
 *   • notes — supplementary text the agent picks up on its next iteration
 *
 * State is in-process (chat-standalone owns the loop) and ephemeral: it is
 * reset when the turn begins and cleared when it ends. Both levers no-op
 * when no turn is running, so the caller can tell the user to just send a
 * normal message instead.
 */

interface TurnControl {
  running: boolean;
  aborted: boolean;
  notes: string[];
}

const controls = new Map<string, TurnControl>();

function get(sessionId: string): TurnControl {
  let c = controls.get(sessionId);
  if (!c) {
    c = { running: false, aborted: false, notes: [] };
    controls.set(sessionId, c);
  }
  return c;
}

/** Mark a turn as live. Resets abort + drains stale notes from any prior turn. */
export function beginTurn(sessionId: string): void {
  const c = get(sessionId);
  c.running = true;
  c.aborted = false;
  c.notes = [];
}

/** Turn finished (normally or via abort) — clear all transient state. */
export function endTurn(sessionId: string): void {
  const c = get(sessionId);
  c.running = false;
  c.aborted = false;
  c.notes = [];
}

/** User asked to stop. Returns false if no turn is running (nothing to abort). */
export function requestAbort(sessionId: string): boolean {
  const c = get(sessionId);
  if (!c.running) return false;
  c.aborted = true;
  return true;
}

export function isAborted(sessionId: string): boolean {
  return get(sessionId).aborted;
}

export function isTurnRunning(sessionId: string): boolean {
  return get(sessionId).running;
}

/** Queue supplementary info for the running turn. Returns false if idle. */
export function addNote(sessionId: string, text: string): boolean {
  const c = get(sessionId);
  if (!c.running) return false;
  c.notes.push(text);
  return true;
}

/** Take + clear the queued notes (called by the loop each iteration). */
export function consumeNotes(sessionId: string): string[] {
  const c = get(sessionId);
  if (c.notes.length === 0) return [];
  const out = c.notes;
  c.notes = [];
  return out;
}
