import { describe, it, expect } from 'vitest';
import { makeNonce, makeMarkerCommand, parseMarker, extractOutput, detectWaitingForInput, shouldGuardInterrupt } from './console-run-lib.js';

describe('console-run-lib', () => {
  it('makeNonce is long, hex, and unique', () => {
    const a = makeNonce(), b = makeNonce();
    expect(a).toMatch(/^[0-9a-f]{24,}$/);
    expect(a).not.toBe(b);
  });
  it('makeMarkerCommand wraps the command with a nonce echo of $?', () => {
    const { text, marker } = makeMarkerCommand('ls -la', 'deadbeef');
    expect(text).toBe('ls -la; echo "__MAESTRO_DONE_deadbeef:$?__"\n');
    expect(marker).toBe('__MAESTRO_DONE_deadbeef:');
  });
  it('parseMarker finds the exit code from output text', () => {
    expect(parseMarker('foo\n__MAESTRO_DONE_deadbeef:0__\n', 'deadbeef')).toEqual({ found: true, exitCode: 0 });
    expect(parseMarker('foo\n__MAESTRO_DONE_deadbeef:130__\n', 'deadbeef')).toEqual({ found: true, exitCode: 130 });
    expect(parseMarker('still running...', 'deadbeef')).toEqual({ found: false, exitCode: null });
    // a different nonce in the stream must NOT match (anti-spoof)
    expect(parseMarker('__MAESTRO_DONE_otheronce:0__', 'deadbeef')).toEqual({ found: false, exitCode: null });
  });
  it('extractOutput strips the echoed command line and the marker line', () => {
    const raw = 'ls -la; echo "__MAESTRO_DONE_dead:$?__"\nfile1\nfile2\n__MAESTRO_DONE_dead:0__\n';
    const out = extractOutput(raw, 'ls -la', 'dead');
    expect(out).toContain('file1');
    expect(out).toContain('file2');
    expect(out).not.toContain('__MAESTRO_DONE_');
  });
  it('detectWaitingForInput spots common prompts in the screen tail', () => {
    expect(detectWaitingForInput('Password: ')).toBe(true);
    expect(detectWaitingForInput('Continue? [y/N] ')).toBe(true);
    expect(detectWaitingForInput('Are you sure (yes/no)? ')).toBe(true);
    expect(detectWaitingForInput('just some output')).toBe(false);
  });
  it('shouldGuardInterrupt: guards when alive, allows when idle or confirmed', () => {
    const now = 1_000_000;
    const alive = { idleMs: 200, msSinceAiInput: 300, sessionAgeMs: 1000 };
    const idle  = { idleMs: 60_000, msSinceAiInput: 60_000, sessionAgeMs: 60_000 };
    expect(shouldGuardInterrupt(alive, false)).toBe(true);   // block
    expect(shouldGuardInterrupt(alive, true)).toBe(false);   // confirmed -> allow
    expect(shouldGuardInterrupt(idle, false)).toBe(false);   // idle -> allow
  });
});
