"use strict";
// src/test_response_structure_extractor.ts
// v1.17.0 — ResponseStructureExtractor regression. Asserts each of the
// 4 dimensions independently + the parseAll convenience.
Object.defineProperty(exports, "__esModule", { value: true });
const ResponseStructureExtractor_1 = require("./orchestrator/util/ResponseStructureExtractor");
function assert(cond, msg) {
    if (!cond)
        throw new Error(`assertion failed: ${msg}`);
}
function deepEq(a, b) {
    return JSON.stringify(a) === JSON.stringify(b);
}
function scenarioExtractFilePaths() {
    const out = (0, ResponseStructureExtractor_1.extractFilePaths)('See `foo/bar.ts:42` and `baz.ts`. Also check `lib/util.js`.');
    assert(deepEq(out, ['foo/bar.ts', 'baz.ts', 'lib/util.js']), `got ${JSON.stringify(out)}`);
    // Dedup
    const dup = (0, ResponseStructureExtractor_1.extractFilePaths)('First `src/a.ts`, then `src/a.ts` again, finally `src/b.ts`.');
    assert(deepEq(dup, ['src/a.ts', 'src/b.ts']), `dedup: got ${JSON.stringify(dup)}`);
    // node_modules filtered
    const nm = (0, ResponseStructureExtractor_1.extractFilePaths)('Path `node_modules/foo/index.js` is noise.');
    assert(deepEq(nm, []), `node_modules should be filtered: got ${JSON.stringify(nm)}`);
    // Scoped package names filtered
    const sc = (0, ResponseStructureExtractor_1.extractFilePaths)('Install `@openlife/cli` not `@scope/pkg`.');
    assert(deepEq(sc, []), `scoped packages filtered: got ${JSON.stringify(sc)}`);
    // Path with line number
    const ln = (0, ResponseStructureExtractor_1.extractFilePaths)('Bug in `src/Gateway.ts:714`.');
    assert(deepEq(ln, ['src/Gateway.ts']), `line numbers stripped: got ${JSON.stringify(ln)}`);
    // No paths
    assert(deepEq((0, ResponseStructureExtractor_1.extractFilePaths)(''), []), 'empty');
    assert(deepEq((0, ResponseStructureExtractor_1.extractFilePaths)('No paths here.'), []), 'no backticks');
    console.log('✅ scenario 1: extractFilePaths — dedup, line-strip, blocklist');
}
function scenarioExtractCodeBlocks() {
    const text = '```ts\nconst x = 1;\n```\n\nThen:\n```python\nprint(2)\n```';
    const blocks = (0, ResponseStructureExtractor_1.extractCodeBlocks)(text);
    assert(blocks.length === 2, `expected 2 blocks, got ${blocks.length}`);
    assert(blocks[0].language === 'ts', `first lang ts, got ${blocks[0].language}`);
    assert(blocks[0].content === 'const x = 1;', `first content`);
    assert(blocks[1].language === 'python', `second lang python`);
    assert(blocks[1].content === 'print(2)', `second content`);
    // Same language twice — preserves order, both kept.
    const dup = (0, ResponseStructureExtractor_1.extractCodeBlocks)('```ts\na\n```\n```ts\nb\n```');
    assert(dup.length === 2, `same-lang twice: ${dup.length}`);
    // Path hint via fence
    const withPath = (0, ResponseStructureExtractor_1.extractCodeBlocks)('```ts src/foo.ts\nexport const X = 1;\n```');
    assert(withPath[0].filePath === 'src/foo.ts', `path hint from fence: got ${withPath[0].filePath}`);
    // Path hint via first-line comment
    const withCmt = (0, ResponseStructureExtractor_1.extractCodeBlocks)('```ts\n// src/bar.ts\nexport const Y = 2;\n```');
    assert(withCmt[0].filePath === 'src/bar.ts', `path hint from comment: got ${withCmt[0].filePath}`);
    assert(withCmt[0].content === 'export const Y = 2;', `comment line removed from content`);
    // No code blocks
    assert(deepEq((0, ResponseStructureExtractor_1.extractCodeBlocks)(''), []), 'empty');
    assert(deepEq((0, ResponseStructureExtractor_1.extractCodeBlocks)('No fences here.'), []), 'no fences');
    // Tag-less fence falls back to 'text'
    const tagless = (0, ResponseStructureExtractor_1.extractCodeBlocks)('```\nplain\n```');
    assert(tagless[0].language === 'text', `tagless → text, got ${tagless[0].language}`);
    console.log('✅ scenario 2: extractCodeBlocks — multi-block, path hints, tagless');
}
function scenarioExtractACsChecked() {
    const md = `
- [x] AC 1 — done
- [ ] AC 2 — pending
- [X] AC 3 — also done
- [ ] AC 4 — pending
`;
    const checked = (0, ResponseStructureExtractor_1.extractACsChecked)(md);
    assert(deepEq(checked, [0, 2]), `got ${JSON.stringify(checked)}`);
    // Numbered list
    const numbered = `
1. [x] First
2. [ ] Second
3. [x] Third
`;
    assert(deepEq((0, ResponseStructureExtractor_1.extractACsChecked)(numbered), [0, 2]), `numbered`);
    // Mixed asterisk + dash
    const mixed = `
* [x] alpha
- [ ] beta
* [x] gamma
`;
    assert(deepEq((0, ResponseStructureExtractor_1.extractACsChecked)(mixed), [0, 2]), `mixed bullets`);
    // No checkboxes
    assert(deepEq((0, ResponseStructureExtractor_1.extractACsChecked)('No items.'), []), 'empty');
    // All unchecked
    assert(deepEq((0, ResponseStructureExtractor_1.extractACsChecked)('- [ ] a\n- [ ] b'), []), 'all unchecked');
    console.log('✅ scenario 3: extractACsChecked — bullets/numbered, mixed cases');
}
function scenarioExtractTestCmd() {
    assert((0, ResponseStructureExtractor_1.extractTestCmd)('Run `npm test src/foo`.') === 'npm test src/foo', 'npm test backtick');
    assert((0, ResponseStructureExtractor_1.extractTestCmd)('Try `npm run test:bridge`.') === 'npm run test:bridge', 'npm run test:bridge');
    assert((0, ResponseStructureExtractor_1.extractTestCmd)('Then `pytest tests/auth -v`.') === 'pytest tests/auth -v', 'pytest');
    assert((0, ResponseStructureExtractor_1.extractTestCmd)('Use `yarn test --watch`.') === 'yarn test --watch', 'yarn');
    // Prose fallback
    assert((0, ResponseStructureExtractor_1.extractTestCmd)('Run: npm test') === 'npm test', 'prose Run:');
    assert((0, ResponseStructureExtractor_1.extractTestCmd)('Tests: pytest tests/') === 'pytest tests/', 'prose Tests:');
    // None
    assert((0, ResponseStructureExtractor_1.extractTestCmd)('') === null, 'empty');
    assert((0, ResponseStructureExtractor_1.extractTestCmd)('No commands here.') === null, 'no commands');
    // Backticked thing that ISN'T a test runner
    assert((0, ResponseStructureExtractor_1.extractTestCmd)('`echo hi`') === null, 'non-runner ignored');
    console.log('✅ scenario 4: extractTestCmd — backtick + prose, runner-aware');
}
function scenarioParseAll() {
    const text = `
I'll fix the gateway.

\`\`\`ts src/Gateway.ts
export class Gateway {
  shutdown() { /* fixed */ }
}
\`\`\`

Update \`src/Gateway.ts\` and run \`npm test src/test_gateway.ts\`.

Acceptance:
- [x] SIGTERM exits within 5s
- [ ] stale state cleanup
`;
    const r = (0, ResponseStructureExtractor_1.parseAll)(text);
    assert(r.filePaths.includes('src/Gateway.ts'), 'filePaths includes Gateway');
    assert(r.codeBlocks.length === 1 && r.codeBlocks[0].filePath === 'src/Gateway.ts', 'codeBlock with path');
    assert(deepEq(r.acsChecked, [0]), `AC 0 checked: got ${JSON.stringify(r.acsChecked)}`);
    assert(r.testCmd === 'npm test src/test_gateway.ts', `test cmd: ${r.testCmd}`);
    console.log('✅ scenario 5: parseAll integrates all four dimensions');
}
try {
    scenarioExtractFilePaths();
    scenarioExtractCodeBlocks();
    scenarioExtractACsChecked();
    scenarioExtractTestCmd();
    scenarioParseAll();
    console.log('TEST_RESPONSE_STRUCTURE_EXTRACTOR_OK');
}
catch (err) {
    console.error('TEST_RESPONSE_STRUCTURE_EXTRACTOR_FAIL', err);
    process.exit(1);
}
