"use strict";
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 os = __importStar(require("os"));
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
describe('Phase 3: Knowledge Graph Store', () => {
    let tmpHome;
    let originalUserProfile;
    let saveFileKG;
    let getFileKG;
    let savePatternEntities;
    let savePatternRels;
    let getPatternStats;
    let saveTech;
    let getTech;
    let computeBlast;
    let getTopBlast;
    let computeBlastRadius;
    let getTopBlastRadii;
    let getInsights;
    let closeDb;
    beforeAll(() => {
        originalUserProfile = process.env.USERPROFILE;
        tmpHome = path.join(os.tmpdir(), 'fivo-cell-phase3-' + Date.now());
        process.env.USERPROFILE = tmpHome;
        fs.mkdirSync(tmpHome, { recursive: true });
        const store = require('../walls/06-memory/stores/knowledge-graph-store');
        saveFileKG = store.saveFileKnowledgeGraph;
        getFileKG = store.getFileKnowledgeGraph;
        savePatternEntities = store.savePatternEntities;
        savePatternRels = store.savePatternRelationships;
        getPatternStats = store.getPatternGraphStats;
        saveTech = store.saveTechProficiency;
        getTech = store.getTechProficiency;
        computeBlast = store.computeBlastRadius;
        getTopBlast = store.getTopBlastRadii;
        computeBlastRadius = store.computeBlastRadius;
        getTopBlastRadii = store.getTopBlastRadii;
        getInsights = store.getPredictiveInsights;
        const db = require('../walls/06-memory/database/database');
        closeDb = db.closeDb;
        closeDb();
    });
    beforeEach(() => {
        const { getDb } = require('../walls/06-memory/database/database');
        const db = getDb();
        db.prepare('DELETE FROM knowledge_graph_files').run();
        db.prepare('DELETE FROM knowledge_graph_deps').run();
        db.prepare('DELETE FROM graph_entities').run();
        db.prepare('DELETE FROM graph_relationships').run();
        db.prepare('DELETE FROM tech_proficiency').run();
        db.prepare('DELETE FROM predictive_insights').run();
    });
    afterAll(() => {
        if (originalUserProfile !== undefined) {
            process.env.USERPROFILE = originalUserProfile;
        }
        else {
            delete process.env.USERPROFILE;
        }
        closeDb();
        try {
            fs.rmSync(tmpHome, { recursive: true, force: true });
        }
        catch { }
    });
    describe('3.1: File Knowledge Graph', () => {
        it('saveFileKnowledgeGraph persists files with complexity', () => {
            const dir = path.join(os.tmpdir(), 'fivo-cell-kg-' + Date.now());
            fs.mkdirSync(path.join(dir, 'src'), { recursive: true });
            fs.writeFileSync(path.join(dir, 'src', 'a.ts'), 'import { b } from "./b";\nfunction hello() { if (true) { return b(); } }\n');
            fs.writeFileSync(path.join(dir, 'src', 'b.ts'), 'export const b = () => 42;\n');
            fs.writeFileSync(path.join(dir, 'src', 'index.ts'), 'import { b } from "./b";\nfor (let i = 0; i < 10; i++) { b(); }\n');
            const graph = saveFileKG('test-proj-3.1-a', dir);
            expect(graph.nodes.length).toBeGreaterThan(0);
            const stored = getFileKG('test-proj-3.1-a');
            expect(stored.files.length).toBeGreaterThan(0);
            expect(stored.stats.totalFiles).toBeGreaterThan(0);
            fs.rmSync(dir, { recursive: true, force: true });
        });
        it('getFileKnowledgeGraph ranks by risk score (complexity × dependents)', () => {
            const dir = path.join(os.tmpdir(), 'fivo-cell-kg-risk-' + Date.now());
            fs.mkdirSync(path.join(dir, 'src'), { recursive: true });
            // 'core' imported by many → high risk
            fs.writeFileSync(path.join(dir, 'src', 'core.ts'), 'export const core = 1;\nif (true) {}\nif (false) {}\nfor (;;) break;\n');
            fs.writeFileSync(path.join(dir, 'src', 'a.ts'), 'import "./core";\n');
            fs.writeFileSync(path.join(dir, 'src', 'b.ts'), 'import "./core";\n');
            fs.writeFileSync(path.join(dir, 'src', 'c.ts'), 'import "./core";\n');
            saveFileKG('test-proj-3.1-b', dir);
            const stored = getFileKG('test-proj-3.1-b');
            const coreFile = stored.files.find(f => f.file.includes('core.ts'));
            expect(coreFile).toBeDefined();
            expect(coreFile.importedBy).toBeGreaterThanOrEqual(3);
            expect(coreFile.riskScore).toBeGreaterThan(0);
            fs.rmSync(dir, { recursive: true, force: true });
        });
    });
    describe('3.2: Pattern Knowledge Graph', () => {
        it('savePatternEntities persists nodes by type', () => {
            savePatternEntities('test-proj-3.2-a', [
                { id: 'p1', type: 'pattern', label: 'factory', weight: 1 },
                { id: 'p2', type: 'pattern', label: 'observer', weight: 2 },
                { id: 'c1', type: 'category', label: 'creational', weight: 1 },
            ]);
            const stats = getPatternStats('test-proj-3.2-a');
            expect(stats.totalNodes).toBe(3);
            expect(stats.byType['pattern']).toBe(2);
            expect(stats.byType['category']).toBe(1);
        });
        it('savePatternRelationships tracks co-occurrences', () => {
            savePatternEntities('test-proj-3.2-b', [
                { id: 'p1', type: 'pattern', label: 'a', weight: 1 },
                { id: 'p2', type: 'pattern', label: 'b', weight: 1 },
            ]);
            savePatternRels('test-proj-3.2-b', [
                { from: 'p1', to: 'p2', type: 'co_occurs', weight: 1 },
                { from: 'p2', to: 'p1', type: 'similar', weight: 0.8 },
            ]);
            const stats = getPatternStats('test-proj-3.2-b');
            expect(stats.totalEdges).toBe(2);
            expect(stats.byRelType['co_occurs']).toBe(1);
            expect(stats.byRelType['similar']).toBe(1);
        });
    });
    describe('3.3: Tech Proficiency', () => {
        it('saveTechProficiency + getTechProficiency round-trips data', () => {
            saveTech('test-proj-3.3-a', {
                technology: 'TypeScript',
                category: 'language',
                signalsCount: 50,
                proficiencyScore: 85,
                lastSeen: new Date().toISOString(),
                trend: 'up',
            });
            saveTech('test-proj-3.3-a', {
                technology: 'Rust',
                category: 'language',
                signalsCount: 5,
                proficiencyScore: 30,
                lastSeen: new Date().toISOString(),
                trend: 'stable',
            });
            const techs = getTech('test-proj-3.3-a');
            expect(techs).toHaveLength(2);
            expect(techs[0].technology).toBe('TypeScript');
            expect(techs[0].proficiencyScore).toBe(85);
            expect(techs[0].trend).toBe('up');
        });
        it('saveTechProficiency accumulates signals on conflict', () => {
            saveTech('test-proj-3.3-b', {
                technology: 'Python',
                category: 'language',
                signalsCount: 10,
                proficiencyScore: 60,
                lastSeen: new Date().toISOString(),
                trend: 'up',
            });
            saveTech('test-proj-3.3-b', {
                technology: 'Python',
                category: 'language',
                signalsCount: 5,
                proficiencyScore: 70,
                lastSeen: new Date().toISOString(),
                trend: 'up',
            });
            const techs = getTech('test-proj-3.3-b');
            expect(techs).toHaveLength(1);
            expect(techs[0].signalsCount).toBe(15);
            expect(techs[0].proficiencyScore).toBe(70);
        });
    });
    describe('3.5: Blast Radius (the surprise feature)', () => {
        it('computeBlastRadius finds transitive dependents', () => {
            const dir = path.join(os.tmpdir(), 'fivo-cell-blast-' + Date.now());
            fs.mkdirSync(path.join(dir, 'src'), { recursive: true });
            fs.writeFileSync(path.join(dir, 'src', 'core.ts'), 'export const x = 1;\n');
            fs.writeFileSync(path.join(dir, 'src', 'a.ts'), 'import "./core";\n');
            fs.writeFileSync(path.join(dir, 'src', 'b.ts'), 'import "./a";\n');
            fs.writeFileSync(path.join(dir, 'src', 'c.ts'), 'import "./b";\n');
            saveFileKG('test-proj-3.5-a', dir);
            const blast = computeBlast('test-proj-3.5-a', 'src/core.ts');
            expect(blast.target).toBe('src/core.ts');
            expect(blast.totalFiles).toBeGreaterThanOrEqual(2);
            expect(blast.recommendation).toMatch(/LOW RISK|MODERATE|HIGH RISK|CRITICAL/);
            fs.rmSync(dir, { recursive: true, force: true });
        });
        it('blast radius insight is saved to predictive_insights', () => {
            const dir = path.join(os.tmpdir(), 'fivo-cell-blast-2-' + Date.now());
            fs.mkdirSync(path.join(dir, 'src'), { recursive: true });
            fs.writeFileSync(path.join(dir, 'src', 'core.ts'), 'export const x = 1;\nif (true) {}\nif (false) {}\nfor (;;) break;\n');
            fs.writeFileSync(path.join(dir, 'src', 'a.ts'), 'import "./core";\n');
            fs.writeFileSync(path.join(dir, 'src', 'b.ts'), 'import "./core";\n');
            saveFileKG('test-proj-3.5-b', dir);
            computeBlast('test-proj-3.5-b', 'src/core.ts');
            const insights = getInsights('test-proj-3.5-b');
            expect(insights.length).toBeGreaterThan(0);
            expect(insights[0].type).toBe('blast_radius');
            expect(insights[0].target).toBe('src/core.ts');
            fs.rmSync(dir, { recursive: true, force: true });
        });
        it('getTopBlastRadii returns highest-risk files', () => {
            const dir = path.join(os.tmpdir(), 'fivo-cell-blast-3-' + Date.now());
            fs.mkdirSync(path.join(dir, 'src'), { recursive: true });
            // Bump complexity to get risk >= 50: need 25+ branching points
            const complexContent = Array(15).fill(0).map((_, i) => `if (x === ${i}) { return ${i}; }`).join('\n') +
                '\n' + Array(5).fill(0).map((_, i) => `for (let i = 0; i < ${i}; i++) { x++; }`).join('\n');
            fs.writeFileSync(path.join(dir, 'src', 'hot.ts'), `export const x = 1;\n${complexContent}\n`);
            fs.writeFileSync(path.join(dir, 'src', 'a.ts'), 'import "./hot";\n');
            fs.writeFileSync(path.join(dir, 'src', 'b.ts'), 'import "./hot";\n');
            fs.writeFileSync(path.join(dir, 'src', 'c.ts'), 'import "./hot";\n');
            saveFileKG('test-proj-3.5-c', dir);
            const top = getTopBlast('test-proj-3.5-c', 5);
            expect(top.length).toBeGreaterThan(0);
            expect(top[0].target).toContain('hot.ts');
            fs.rmSync(dir, { recursive: true, force: true });
        });
    });
});
//# sourceMappingURL=knowledge-graph-store.test.js.map