"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.initFailureMemoryTable = initFailureMemoryTable;
exports.recordFailure = recordFailure;
exports.getAvoidSuggestions = getAvoidSuggestions;
exports.getFailureStats = getFailureStats;
exports.getFailureRecord = getFailureRecord;
exports.getAllFailureRecords = getAllFailureRecords;
exports.clearFailures = clearFailures;
exports.persistEngineeringLesson = persistEngineeringLesson;
exports.getEngineeringLessons = getEngineeringLessons;
exports.getLessonByPattern = getLessonByPattern;
exports.formatEngineeringLesson = formatEngineeringLesson;
const database_1 = require("../../06-memory/database/database");
const FAILURE_THRESHOLD = 0.5;
function initFailureMemoryTable() {
    const db = (0, database_1.getDb)();
    db.exec(`
    CREATE TABLE IF NOT EXISTS failure_memory (
      pattern_id TEXT PRIMARY KEY,
      description TEXT,
      from_pattern TEXT,
      to_pattern TEXT,
      reject_count INTEGER DEFAULT 0,
      accept_count INTEGER DEFAULT 0,
      total_signals INTEGER DEFAULT 0,
      failure_rate REAL DEFAULT 0,
      last_rejected INTEGER DEFAULT 0,
      category TEXT,
      language TEXT DEFAULT 'unknown',
      common_alternatives TEXT DEFAULT '[]',
      project TEXT,
      updated_at TEXT DEFAULT (datetime('now'))
    );
    CREATE INDEX IF NOT EXISTS idx_failure_memory_category ON failure_memory(category);
    CREATE INDEX IF NOT EXISTS idx_failure_memory_rate ON failure_memory(failure_rate DESC);
    CREATE INDEX IF NOT EXISTS idx_failure_memory_project ON failure_memory(project);

    CREATE TABLE IF NOT EXISTS engineering_lessons (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      pattern_id TEXT NOT NULL,
      description TEXT NOT NULL,
      category TEXT,
      language TEXT DEFAULT 'unknown',
      failure_rate REAL DEFAULT 0,
      alternative TEXT,
      learned_at TEXT DEFAULT (datetime('now')),
      project TEXT,
      created_at TEXT DEFAULT (datetime('now'))
    );
    CREATE INDEX IF NOT EXISTS idx_lessons_project ON engineering_lessons(project);
    CREATE INDEX IF NOT EXISTS idx_lessons_category ON engineering_lessons(category);
  `);
}
function recordFailure(pattern, isReject, language = 'unknown', project) {
    const db = (0, database_1.getDb)();
    initFailureMemoryTable();
    const key = pattern.patternId;
    const existing = db.prepare('SELECT * FROM failure_memory WHERE pattern_id = ?').get(key);
    let rejectCount = 0;
    let acceptCount = 0;
    let totalSignals = 0;
    let lastRejected = 0;
    if (existing) {
        rejectCount = Number(existing.reject_count) || 0;
        acceptCount = Number(existing.accept_count) || 0;
        totalSignals = Number(existing.total_signals) || 0;
        lastRejected = Number(existing.last_rejected) || 0;
    }
    totalSignals++;
    if (isReject) {
        rejectCount++;
        lastRejected = Date.now();
    }
    else {
        acceptCount++;
    }
    const failureRate = totalSignals > 0 ? rejectCount / totalSignals : 0;
    db.prepare(`
    INSERT INTO failure_memory (pattern_id, description, from_pattern, to_pattern, reject_count, accept_count, total_signals, failure_rate, last_rejected, category, language, common_alternatives, project, updated_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))
    ON CONFLICT(pattern_id) DO UPDATE SET
      reject_count = excluded.reject_count,
      accept_count = excluded.accept_count,
      total_signals = excluded.total_signals,
      failure_rate = excluded.failure_rate,
      last_rejected = CASE WHEN excluded.last_rejected > failure_memory.last_rejected THEN excluded.last_rejected ELSE failure_memory.last_rejected END,
      common_alternatives = excluded.common_alternatives,
      updated_at = datetime('now')
  `).run(key, pattern.description, pattern.from, pattern.to, rejectCount, acceptCount, totalSignals, failureRate, lastRejected, pattern.category, language, '[]', project || null);
    return {
        patternId: key,
        description: pattern.description,
        from: pattern.from,
        to: pattern.to,
        rejectCount,
        acceptCount,
        totalSignals,
        failureRate,
        lastRejected,
        category: pattern.category,
        language,
        commonAlternatives: [],
    };
}
function getAvoidSuggestions(minFailureRate = FAILURE_THRESHOLD, project) {
    const db = (0, database_1.getDb)();
    initFailureMemoryTable();
    const where = project ? 'WHERE project = ? AND failure_rate >= ? AND total_signals >= 3' : 'WHERE failure_rate >= ? AND total_signals >= 3';
    const params = project ? [project, minFailureRate] : [minFailureRate];
    const rows = db.prepare(`
    SELECT pattern_id, description, failure_rate, reject_count, total_signals, category, language, common_alternatives
    FROM failure_memory
    ${where}
    ORDER BY failure_rate DESC
  `).all(...params);
    const suggestions = [];
    for (const row of rows) {
        const rate = Number(row.failure_rate) || 0;
        let severity;
        if (rate >= 0.8)
            severity = 'critical';
        else if (rate >= 0.7)
            severity = 'high';
        else if (rate >= 0.6)
            severity = 'medium';
        else
            severity = 'low';
        const alternatives = findAlternativesByCategory(String(row.category), String(row.language));
        const reason = `Rejected ${row.reject_count}/${row.total_signals} times (${Math.round(rate * 100)}% failure rate)`;
        let alternativesFromRow = [];
        try {
            alternativesFromRow = JSON.parse(String(row.common_alternatives || '[]'));
        }
        catch { }
        const allAlts = [...alternativesFromRow, ...alternatives.map(a => a.description)];
        const uniqueAlts = Array.from(new Set(allAlts));
        suggestions.push({
            patternId: String(row.pattern_id),
            description: String(row.description || ''),
            failureRate: rate,
            severity,
            reason,
            alternativeDescription: uniqueAlts.length > 0
                ? `Consider: ${uniqueAlts[0]}`
                : 'No clear alternative found',
            developerCount: 1,
        });
    }
    return suggestions.sort((a, b) => b.failureRate - a.failureRate);
}
function getFailureStats(project) {
    const db = (0, database_1.getDb)();
    initFailureMemoryTable();
    const where = project ? 'WHERE project = ?' : '';
    const params = project ? [project] : [];
    const rows = db.prepare(`SELECT failure_rate FROM failure_memory ${where}`).all(...params);
    const total = rows.length;
    let critical = 0, high = 0, medium = 0, low = 0;
    for (const r of rows) {
        const rate = Number(r.failure_rate) || 0;
        if (rate >= 0.8)
            critical++;
        else if (rate >= 0.7)
            high++;
        else if (rate >= 0.6)
            medium++;
        else if (rate >= FAILURE_THRESHOLD)
            low++;
    }
    return {
        totalTracked: total,
        criticalCount: critical,
        highCount: high,
        mediumCount: medium,
        lowCount: low,
        avgFailureRate: total > 0
            ? rows.reduce((s, r) => s + (Number(r.failure_rate) || 0), 0) / total
            : 0,
    };
}
function findAlternativesByCategory(category, language) {
    const db = (0, database_1.getDb)();
    initFailureMemoryTable();
    const results = [];
    try {
        const rows = db.prepare(`
      SELECT pattern_id, description, failure_rate
      FROM failure_memory
      WHERE category = ? AND language = ? AND failure_rate < 0.3 AND total_signals >= 2
      ORDER BY failure_rate ASC
      LIMIT 3
    `).all(category, language);
        for (const row of rows) {
            results.push({
                patternId: String(row.pattern_id),
                description: String(row.description || ''),
                successRate: 1 - (Number(row.failure_rate) || 0),
            });
        }
    }
    catch { }
    try {
        const codeRows = db.prepare(`
      SELECT pattern_value, category, trust_score
      FROM code_patterns
      WHERE category = ? AND trust_score > 0.7
      ORDER BY count DESC
      LIMIT 3
    `).all(category);
        for (const row of codeRows) {
            if (!results.some(r => r.description === String(row.pattern_value))) {
                results.push({
                    patternId: `code_pattern:${row.pattern_value}`,
                    description: String(row.pattern_value || ''),
                    successRate: Number(row.trust_score) || 0.7,
                });
            }
        }
    }
    catch { }
    try {
        const patternRows = db.prepare(`
      SELECT id, rule, category, confidence
      FROM patterns
      WHERE category = ? AND confidence > 0.7
      ORDER BY success_count DESC
      LIMIT 3
    `).all(category);
        for (const row of patternRows) {
            if (!results.some(r => r.patternId === String(row.id))) {
                results.push({
                    patternId: String(row.id),
                    description: String(row.rule || ''),
                    successRate: Number(row.confidence) || 0.7,
                });
            }
        }
    }
    catch { }
    return results.slice(0, 5);
}
function getFailureRecord(patternId) {
    const db = (0, database_1.getDb)();
    initFailureMemoryTable();
    const row = db.prepare('SELECT * FROM failure_memory WHERE pattern_id = ?').get(patternId);
    if (!row)
        return undefined;
    let alternatives = [];
    try {
        alternatives = JSON.parse(String(row.common_alternatives || '[]'));
    }
    catch { }
    return {
        patternId: String(row.pattern_id),
        description: String(row.description || ''),
        from: String(row.from_pattern || ''),
        to: String(row.to_pattern || ''),
        rejectCount: Number(row.reject_count) || 0,
        acceptCount: Number(row.accept_count) || 0,
        totalSignals: Number(row.total_signals) || 0,
        failureRate: Number(row.failure_rate) || 0,
        lastRejected: Number(row.last_rejected) || 0,
        category: String(row.category || ''),
        language: String(row.language || 'unknown'),
        commonAlternatives: alternatives,
    };
}
function getAllFailureRecords(project) {
    const db = (0, database_1.getDb)();
    initFailureMemoryTable();
    const where = project ? 'WHERE project = ?' : '';
    const params = project ? [project] : [];
    const rows = db.prepare(`SELECT * FROM failure_memory ${where} ORDER BY failure_rate DESC`).all(...params);
    return rows.map(row => {
        let alternatives = [];
        try {
            alternatives = JSON.parse(String(row.common_alternatives || '[]'));
        }
        catch { }
        return {
            patternId: String(row.pattern_id),
            description: String(row.description || ''),
            from: String(row.from_pattern || ''),
            to: String(row.to_pattern || ''),
            rejectCount: Number(row.reject_count) || 0,
            acceptCount: Number(row.accept_count) || 0,
            totalSignals: Number(row.total_signals) || 0,
            failureRate: Number(row.failure_rate) || 0,
            lastRejected: Number(row.last_rejected) || 0,
            category: String(row.category || ''),
            language: String(row.language || 'unknown'),
            commonAlternatives: alternatives,
        };
    });
}
function clearFailures(project) {
    const db = (0, database_1.getDb)();
    initFailureMemoryTable();
    if (project) {
        db.prepare('DELETE FROM failure_memory WHERE project = ?').run(project);
    }
    else {
        db.prepare('DELETE FROM failure_memory').run();
    }
}
// ============================================================
// Engineering Lessons Persistence (3B)
// ============================================================
function persistEngineeringLesson(patternId, description, category, language, failureRate, alternative, project) {
    const db = (0, database_1.getDb)();
    initFailureMemoryTable();
    const result = db.prepare(`
    INSERT INTO engineering_lessons (pattern_id, description, category, language, failure_rate, alternative, project)
    VALUES (?, ?, ?, ?, ?, ?, ?)
  `).run(patternId, description, category, language, failureRate, alternative, project || null);
    return {
        id: result.lastInsertRowid,
        patternId,
        description,
        category,
        language,
        failureRate,
        alternative,
        learnedAt: new Date().toISOString(),
        project: project || '',
    };
}
function getEngineeringLessons(project, limit = 20) {
    const db = (0, database_1.getDb)();
    initFailureMemoryTable();
    const where = project ? 'WHERE project = ?' : '';
    const params = project ? [project, limit] : [limit];
    const rows = db.prepare(`
    SELECT * FROM engineering_lessons ${where}
    ORDER BY failure_rate DESC, created_at DESC
    LIMIT ?
  `).all(...params);
    return rows.map(row => ({
        id: row.id,
        patternId: row.pattern_id,
        description: row.description,
        category: row.category,
        language: row.language,
        failureRate: row.failure_rate,
        alternative: row.alternative,
        learnedAt: row.learned_at,
        project: row.project,
    }));
}
function getLessonByPattern(patternId) {
    const db = (0, database_1.getDb)();
    initFailureMemoryTable();
    const row = db.prepare(`
    SELECT * FROM engineering_lessons WHERE pattern_id = ? ORDER BY created_at DESC LIMIT 1
  `).get(patternId);
    if (!row)
        return null;
    return {
        id: row.id,
        patternId: row.pattern_id,
        description: row.description,
        category: row.category,
        language: row.language,
        failureRate: row.failure_rate,
        alternative: row.alternative,
        learnedAt: row.learned_at,
        project: row.project,
    };
}
function formatEngineeringLesson(lesson) {
    const severity = lesson.failureRate >= 0.8 ? '🔴 CRITICAL' : lesson.failureRate >= 0.6 ? '🟠 HIGH' : '🟡 MEDIUM';
    return `${severity}: ${lesson.description}\n  Category: ${lesson.category} | Language: ${lesson.language}\n  Failure Rate: ${Math.round(lesson.failureRate * 100)}%\n  Alternative: ${lesson.alternative || 'None suggested'}\n  Learned: ${lesson.learnedAt}`;
}
//# sourceMappingURL=failure-memory.js.map