"use strict";
// src/test_graph_large_file.ts
// v1.14.1 — Issue #10 regression.
//
// tree-sitter@0.21 Node bindings throw "Invalid argument" when source
// length > ~32KB and the entire string is passed at once. Symptom: large
// project files (Gateway.ts, src/index.ts, etc.) were silently dropped
// from the graph DB as "failures", losing critical symbols.
//
// Fix: TreeSitterRegistry.parseFile uses the streaming-callback input API
// which has no per-chunk size limit. This test asserts the fix holds for
// sources well above the 32KB threshold.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const SymbolExtractor_1 = require("./orchestrator/graph/SymbolExtractor");
function assert(cond, msg) {
    if (!cond)
        throw new Error(`assertion failed: ${msg}`);
}
function mkLargeSource(approxBytes) {
    const stub = `
export class WidgetN {
  constructor(public id: number) {}
  describe(): string { return \`widget #\${this.id}\`; }
  static fromString(s: string): WidgetN { return new WidgetN(parseInt(s, 10)); }
}

export function processN(input: string): { ok: boolean; payload: WidgetN[] } {
  const items = input.split(',').map(WidgetN.fromString);
  return { ok: items.length > 0, payload: items };
}

`;
    const out = [];
    let totalBytes = 0;
    let i = 0;
    while (totalBytes < approxBytes) {
        const next = stub.replace(/WidgetN/g, `Widget${i}`).replace(/processN/g, `process${i}`);
        out.push(next);
        totalBytes += next.length;
        i++;
    }
    return out.join('');
}
function scenarioLargeFile() {
    const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'graph-large-'));
    try {
        const file = path.join(tmp, 'large.ts');
        // 64KB — twice the tree-sitter@0.21 string-input threshold.
        const source = mkLargeSource(64 * 1024);
        fs.writeFileSync(file, source, 'utf-8');
        assert(source.length > 32 * 1024, `precondition: source > 32KB (got ${source.length})`);
        const syms = (0, SymbolExtractor_1.extractSymbols)(file, source);
        assert(syms.length > 0, 'large file must extract at least one symbol');
        const classes = syms.filter(s => s.kind === 'class');
        const functions = syms.filter(s => s.kind === 'function');
        assert(classes.length >= 10, `expected >=10 classes, got ${classes.length}`);
        assert(functions.length >= 10, `expected >=10 functions, got ${functions.length}`);
        // First and last symbols must both be present — proves streaming
        // input read the entire file, not just the first 32KB.
        assert(syms.some(s => s.name === 'Widget0'), 'first class Widget0 missing');
        const widgetClasses = classes.map(s => s.name);
        const lastIdx = Math.max(...widgetClasses.map(n => parseInt(n.replace('Widget', ''), 10) || 0));
        assert(lastIdx >= 5, `expected high-indexed Widget classes from the file tail, top was ${lastIdx}`);
        console.log(`✅ scenario 1: 64KB source extracted ${syms.length} symbols (classes=${classes.length} functions=${functions.length})`);
    }
    finally {
        try {
            fs.rmSync(tmp, { recursive: true, force: true });
        }
        catch { /* ignore */ }
    }
}
function scenarioNearThreshold() {
    const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'graph-thresh-'));
    try {
        const file = path.join(tmp, 'medium.ts');
        // Just above the 32768 byte boundary that v1.14.0 crashed on.
        const source = mkLargeSource(33 * 1024);
        fs.writeFileSync(file, source, 'utf-8');
        const syms = (0, SymbolExtractor_1.extractSymbols)(file, source);
        assert(syms.length > 0, 'near-threshold file must extract symbols');
        console.log(`✅ scenario 2: 33KB source extracted ${syms.length} symbols (just above v1.14.0 crash threshold)`);
    }
    finally {
        try {
            fs.rmSync(tmp, { recursive: true, force: true });
        }
        catch { /* ignore */ }
    }
}
function scenarioRealRepoFile() {
    // Smoke: try Gateway.ts from the actual repo. It is ~58KB and was
    // the canonical regression case. Skip silently when running outside
    // a tree where the file exists.
    const candidates = [
        path.join(process.cwd(), 'src', 'orchestrator', 'Gateway.ts'),
        '/mnt/d/VSCODDE-DEV/openlife-core-main/src/orchestrator/Gateway.ts',
    ];
    let file = null;
    for (const c of candidates) {
        try {
            if (fs.statSync(c).isFile()) {
                file = c;
                break;
            }
        }
        catch { /* try next */ }
    }
    if (!file) {
        console.log('✓ scenario 3 skipped (Gateway.ts not reachable from cwd)');
        return;
    }
    const src = fs.readFileSync(file, 'utf-8');
    const syms = (0, SymbolExtractor_1.extractSymbols)(file, src);
    assert(syms.length > 0, `Gateway.ts must extract symbols (got ${syms.length})`);
    const hasGatewayClass = syms.some(s => s.kind === 'class' && s.name === 'Gateway');
    assert(hasGatewayClass, 'class Gateway must be in the symbol list');
    const hasShutdown = syms.some(s => s.name === 'Gateway.shutdown');
    assert(hasShutdown, 'Gateway.shutdown method must be in the symbol list');
    console.log(`✅ scenario 3: Gateway.ts (real repo, ${src.length} bytes) extracted ${syms.length} symbols including class Gateway + Gateway.shutdown`);
}
try {
    scenarioLargeFile();
    scenarioNearThreshold();
    scenarioRealRepoFile();
    console.log('TEST_GRAPH_LARGE_FILE_OK');
}
catch (err) {
    console.error('TEST_GRAPH_LARGE_FILE_FAIL', err);
    process.exit(1);
}
