"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 });
exports.saveFileKnowledgeGraph = saveFileKnowledgeGraph;
exports.getFileKnowledgeGraph = getFileKnowledgeGraph;
exports.savePatternEntities = savePatternEntities;
exports.savePatternRelationships = savePatternRelationships;
exports.getPatternGraphStats = getPatternGraphStats;
exports.saveTechProficiency = saveTechProficiency;
exports.getTechProficiency = getTechProficiency;
exports.computeBlastRadius = computeBlastRadius;
exports.getTopBlastRadii = getTopBlastRadii;
exports.getPredictiveInsights = getPredictiveInsights;
const database_1 = require("../database/database");
const knowledge_graph_builder_1 = require("../../03-knowledge/graph/knowledge-graph-builder");
const path = __importStar(require("path"));
function ensureKGProjectDir(project) {
    return project;
}
function saveFileKnowledgeGraph(project, dirPath) {
    const db = (0, database_1.getDb)();
    const graph = (0, knowledge_graph_builder_1.buildKnowledgeGraph)(dirPath);
    db.prepare('DELETE FROM knowledge_graph_files WHERE project = ?').run(project);
    db.prepare('DELETE FROM knowledge_graph_deps WHERE project = ?').run(project);
    const insertFile = db.prepare(`
    INSERT OR REPLACE INTO knowledge_graph_files
      (project, file_path, complexity, import_count, imported_by_count, is_entry_point, risk_score, built_at)
    VALUES (?, ?, ?, ?, ?, ?, 0, datetime('now'))
  `);
    const insertDep = db.prepare(`
    INSERT OR IGNORE INTO knowledge_graph_deps (project, from_file, to_file, built_at)
    VALUES (?, ?, ?, datetime('now'))
  `);
    const insertFiles = db.transaction((nodes) => {
        for (const n of nodes) {
            insertFile.run(project, n.file.split(path.sep).join('/'), n.complexity, n.imports.length, n.importedBy.length, n.isEntryPoint ? 1 : 0);
        }
    });
    const insertDeps = db.transaction((nodes) => {
        for (const n of nodes) {
            for (const dep of n.imports) {
                insertDep.run(project, n.file.split(path.sep).join('/'), dep.split(path.sep).join('/'));
            }
        }
    });
    insertFiles(graph.nodes);
    insertDeps(graph.nodes);
    // Compute risk score = complexity * (importedBy + 1)
    for (const n of graph.nodes) {
        const dependents = n.importedBy.length;
        const risk = Math.min(100, Math.round(n.complexity * (dependents + 1) / 2));
        db.prepare('UPDATE knowledge_graph_files SET risk_score = ? WHERE project = ? AND file_path = ?')
            .run(risk, project, n.file.split(path.sep).join('/'));
    }
    return graph;
}
function getFileKnowledgeGraph(project) {
    const db = (0, database_1.getDb)();
    const files = db.prepare(`
    SELECT file_path, complexity, imported_by_count, is_entry_point, risk_score
    FROM knowledge_graph_files WHERE project = ? ORDER BY risk_score DESC, complexity DESC
  `).all(project);
    const deps = db.prepare(`
    SELECT from_file, to_file FROM knowledge_graph_deps WHERE project = ?
  `).all(project);
    const totalComplexity = files.reduce((s, f) => s + f.complexity, 0);
    const highRisk = files.filter(f => f.risk_score >= 50).length;
    return {
        files: files.map(f => ({
            file: f.file_path,
            complexity: f.complexity,
            importedBy: f.imported_by_count,
            isEntryPoint: f.is_entry_point === 1,
            riskScore: f.risk_score,
        })),
        deps: deps.map(d => ({ from: d.from_file, to: d.to_file })),
        stats: {
            totalFiles: files.length,
            totalDeps: deps.length,
            avgComplexity: files.length > 0 ? Math.round(totalComplexity / files.length) : 0,
            highRiskCount: highRisk,
        },
    };
}
function savePatternEntities(project, nodes) {
    const db = (0, database_1.getDb)();
    const stmt = db.prepare(`
    INSERT OR REPLACE INTO graph_entities (entity_name, entity_type, pattern_id, weight, built_at)
    VALUES (?, ?, ?, ?, datetime('now'))
  `);
    let count = 0;
    const tx = db.transaction((ns) => {
        for (const n of ns) {
            stmt.run(n.id, n.type, n.id, n.weight);
            count++;
        }
    });
    tx(nodes);
    return count;
}
function savePatternRelationships(project, edges) {
    const db = (0, database_1.getDb)();
    const stmt = db.prepare(`
    INSERT OR REPLACE INTO graph_relationships (from_pattern, to_pattern, rel_type, strength, built_at)
    VALUES (?, ?, ?, ?, datetime('now'))
  `);
    let count = 0;
    const tx = db.transaction((es) => {
        for (const e of es) {
            stmt.run(e.from, e.to, e.type, e.weight);
            count++;
        }
    });
    tx(edges);
    return count;
}
function getPatternGraphStats(project) {
    const db = (0, database_1.getDb)();
    const nodes = db.prepare('SELECT entity_type, COUNT(*) as c FROM graph_entities GROUP BY entity_type').all();
    const edges = db.prepare('SELECT rel_type, COUNT(*) as c FROM graph_relationships GROUP BY rel_type').all();
    return {
        totalNodes: nodes.reduce((s, n) => s + n.c, 0),
        totalEdges: edges.reduce((s, e) => s + e.c, 0),
        byType: Object.fromEntries(nodes.map(n => [n.entity_type, n.c])),
        byRelType: Object.fromEntries(edges.map(e => [e.rel_type, e.c])),
    };
}
function saveTechProficiency(project, tech) {
    const db = (0, database_1.getDb)();
    db.prepare(`
    INSERT INTO tech_proficiency (project, technology, category, signals_count, proficiency_score, last_seen, trend)
    VALUES (?, ?, ?, ?, ?, ?, ?)
    ON CONFLICT(project, technology) DO UPDATE SET
      category = excluded.category,
      signals_count = tech_proficiency.signals_count + excluded.signals_count,
      proficiency_score = MAX(tech_proficiency.proficiency_score, excluded.proficiency_score),
      last_seen = excluded.last_seen,
      trend = excluded.trend
  `).run(project, tech.technology, tech.category, tech.signalsCount, tech.proficiencyScore, tech.lastSeen, tech.trend);
}
function getTechProficiency(project) {
    const db = (0, database_1.getDb)();
    const rows = db.prepare(`
    SELECT technology, category, signals_count, proficiency_score, last_seen, trend
    FROM tech_proficiency WHERE project = ? ORDER BY proficiency_score DESC
  `).all(project);
    return rows.map(r => ({
        technology: r.technology,
        category: r.category,
        signalsCount: r.signals_count,
        proficiencyScore: r.proficiency_score,
        lastSeen: r.last_seen,
        trend: r.trend,
    }));
}
// Phase 3.5: Blast radius — given a risky file, find all dependents
function computeBlastRadius(project, targetFile) {
    const db = (0, database_1.getDb)();
    const target = targetFile.split(path.sep).join('/');
    // BFS to find all transitive dependents
    const visited = new Set();
    const queue = [target];
    const dependents = new Set();
    while (queue.length > 0) {
        const current = queue.shift();
        if (visited.has(current))
            continue;
        visited.add(current);
        const rows = db.prepare(`
      SELECT from_file FROM knowledge_graph_deps WHERE project = ? AND to_file = ?
    `).all(project, current.split(path.sep).join('/'));
        for (const r of rows) {
            if (!visited.has(r.from_file)) {
                dependents.add(r.from_file);
                queue.push(r.from_file);
            }
        }
    }
    const fileRow = db.prepare(`
    SELECT complexity, risk_score FROM knowledge_graph_files WHERE project = ? AND file_path = ?
  `).get(project, target);
    const complexity = fileRow?.complexity || 0;
    const totalDependents = dependents.size;
    // Blast radius = complexity * log(dependents + 1), capped at 100
    const blast = Math.min(100, Math.round(complexity * Math.log(totalDependents + 1)));
    let recommendation = '';
    if (blast >= 75) {
        recommendation = `CRITICAL: changes to ${target} will impact ${totalDependents} files. Add regression tests before editing.`;
    }
    else if (blast >= 50) {
        recommendation = `HIGH RISK: ${totalDependents} dependents. Test all of them after changes.`;
    }
    else if (blast >= 25) {
        recommendation = `MODERATE: ${totalDependents} dependents. Spot-check related code.`;
    }
    else {
        recommendation = `LOW RISK: ${totalDependents} dependents. Safe to refactor.`;
    }
    // Save insight
    db.prepare(`
    INSERT INTO predictive_insights (project, insight_type, target, score, recommendation)
    VALUES (?, 'blast_radius', ?, ?, ?)
  `).run(project, target, blast, recommendation);
    return {
        target,
        riskScore: blast,
        dependents: Array.from(dependents).slice(0, 20),
        totalFiles: totalDependents,
        complexity,
        recommendation,
    };
}
function getTopBlastRadii(project, limit = 5) {
    const db = (0, database_1.getDb)();
    const rows = db.prepare(`
    SELECT file_path FROM knowledge_graph_files
    WHERE project = ? AND risk_score >= 50
    ORDER BY risk_score DESC LIMIT ?
  `).all(project, limit);
    return rows.map(r => computeBlastRadius(project, r.file_path));
}
function getPredictiveInsights(project, limit = 20) {
    const db = (0, database_1.getDb)();
    const rows = db.prepare(`
    SELECT insight_type, target, score, recommendation, created_at
    FROM predictive_insights WHERE project = ?
    ORDER BY score DESC, created_at DESC LIMIT ?
  `).all(project, limit);
    return rows.map(r => ({
        type: r.insight_type,
        target: r.target,
        score: r.score,
        recommendation: r.recommendation,
        createdAt: r.created_at,
    }));
}
//# sourceMappingURL=knowledge-graph-store.js.map