import { randomBytes } from 'node:crypto';

const MARKER_PREFIX = '__MAESTRO_DONE_';

export function makeNonce(): string {
  return randomBytes(16).toString('hex');
}

export function makeMarkerCommand(command: string, nonce: string): { text: string; marker: string } {
  const marker = `${MARKER_PREFIX}${nonce}:`;
  // `$?` after `command;` reflects the command's exit code.
  return { text: `${command}; echo "${marker}$?__"\n`, marker };
}

export function parseMarker(text: string, nonce: string): { found: boolean; exitCode: number | null } {
  const re = new RegExp(`${MARKER_PREFIX}${nonce}:(\\d+)__`);
  const m = re.exec(text);
  if (!m) return { found: false, exitCode: null };
  return { found: true, exitCode: Number(m[1]) };
}

// Best-effort: drop the echoed command line and the marker line(s). PTY echo /
// prompt noise may remain — perfect formatting is a non-goal.
export function extractOutput(raw: string, command: string, nonce: string): string {
  const markerRe = new RegExp(`${MARKER_PREFIX}${nonce}:.*?__`);
  return raw
    .split('\n')
    .filter((line) => !markerRe.test(line))
    .filter((line) => line.trim() !== `${command}; echo "${MARKER_PREFIX}${nonce}:$?__"`)
    .join('\n');
}

const WAITING_RE = /(password:|\[y\/n\]|\(yes\/no\)\??|continue\?|press .*key|passphrase:)\s*$/i;
export function detectWaitingForInput(screenTail: string): boolean {
  const lastLines = screenTail.split('\n').slice(-3).join('\n').trim();
  return WAITING_RE.test(lastLines);
}

export interface InterruptLiveness { idleMs: number; msSinceAiInput: number; sessionAgeMs: number; }
const GUARD_IDLE_MS = 3000, GUARD_RECENT_INPUT_MS = 5000, GUARD_SESSION_AGE_MS = 5000;
export function shouldGuardInterrupt(l: InterruptLiveness, confirmInterrupt: boolean): boolean {
  if (confirmInterrupt) return false;
  const alive = l.idleMs < GUARD_IDLE_MS || l.msSinceAiInput < GUARD_RECENT_INPUT_MS || l.sessionAgeMs < GUARD_SESSION_AGE_MS;
  return alive; // true => block the interrupt
}
