"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 5: Community Store', () => {
    let tmpHome;
    let originalUserProfile;
    let closeDb;
    beforeAll(() => {
        originalUserProfile = process.env.USERPROFILE;
        tmpHome = path.join(os.tmpdir(), 'fivo-cell-phase5-' + Date.now());
        process.env.USERPROFILE = tmpHome;
        fs.mkdirSync(tmpHome, { recursive: true });
        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 community_patterns').run();
        db.prepare('DELETE FROM community_insights').run();
        db.prepare('DELETE FROM community_benchmarks').run();
        db.prepare('DELETE FROM tech_proficiency').run();
        db.prepare('DELETE FROM error_log').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('5.1: Privacy Validation', () => {
        it('rejects rules with email-like patterns', async () => {
            const { validatePrivacy } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const result = validatePrivacy('contact me at john.doe@example.com for help');
            expect(result.safe).toBe(false);
            expect(result.errors.length).toBeGreaterThan(0);
            expect(result.errors[0]).toContain('email');
        });
        it('rejects rules with IP addresses', async () => {
            const { validatePrivacy } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const result = validatePrivacy('server is at 192.168.1.1 for testing');
            expect(result.safe).toBe(false);
            expect(result.errors[0]).toContain('IP');
        });
        it('warns on function definitions but allows after sanitization', async () => {
            const { validatePrivacy } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const result = validatePrivacy('use function calculate() with const x = 5');
            expect(result.safe).toBe(true);
            expect(result.warnings.length).toBeGreaterThan(0);
        });
        it('sanitizes file paths', async () => {
            const { validatePrivacy } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const result = validatePrivacy('see file utils.ts and app.js for details');
            expect(result.sanitized).toContain('<file>');
            expect(result.sanitized).not.toContain('utils.ts');
        });
        it('sanitizes numbers', async () => {
            const { validatePrivacy } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const result = validatePrivacy('limit 100 items per page');
            expect(result.sanitized).toContain('<num>');
        });
    });
    describe('5.1/5.2: Share patterns', () => {
        it('shares a safe pattern and returns patternId', async () => {
            const { shareCommunityPattern, getCommunityPatterns } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const result = shareCommunityPattern({
                category: 'naming_style',
                rule: 'Use camelCase for variables',
                language: 'typescript',
                successRate: 0.95,
            });
            expect(result.patternId).toBeDefined();
            expect(result.privacySafe).toBe(true);
            const patterns = getCommunityPatterns();
            expect(patterns.length).toBe(1);
            expect(patterns[0].category).toBe('naming_style');
            expect(patterns[0].language).toBe('typescript');
            expect(patterns[0].successRate).toBe(0.95);
        });
        it('filters patterns by category and language', async () => {
            const { shareCommunityPattern, getCommunityPatterns } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            shareCommunityPattern({ category: 'naming_style', rule: 'camelCase', language: 'typescript' });
            shareCommunityPattern({ category: 'naming_style', rule: 'snake_case', language: 'python' });
            shareCommunityPattern({ category: 'error_handling', rule: 'try-catch', language: 'typescript' });
            expect(getCommunityPatterns({ language: 'typescript' }).length).toBe(2);
            expect(getCommunityPatterns({ category: 'naming_style' }).length).toBe(2);
            expect(getCommunityPatterns({ category: 'naming_style', language: 'python' }).length).toBe(1);
        });
    });
    describe('5.2: Voting + usage', () => {
        it('upvote increments votes, downvote decrements', async () => {
            const { shareCommunityPattern, voteCommunityPattern, getCommunityPatterns } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const { patternId } = shareCommunityPattern({ category: 'naming_style', rule: 'camelCase' });
            voteCommunityPattern(patternId, true);
            voteCommunityPattern(patternId, true);
            voteCommunityPattern(patternId, true);
            voteCommunityPattern(patternId, false);
            const patterns = getCommunityPatterns();
            expect(patterns[0].votes).toBe(2);
        });
        it('increments usage_count on incrementUsage', async () => {
            const { shareCommunityPattern, incrementUsage, getCommunityPatterns } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const { patternId } = shareCommunityPattern({ category: 'test', rule: 'mock all dependencies' });
            incrementUsage(patternId);
            incrementUsage(patternId);
            const patterns = getCommunityPatterns();
            expect(patterns[0].usageCount).toBe(3); // 1 initial + 2 increments
        });
    });
    describe('5.3: Failure patterns', () => {
        it('returns failure patterns from error_log', async () => {
            const { getDb } = require('../walls/06-memory/database/database');
            const db = getDb();
            for (let i = 0; i < 3; i++) {
                db.prepare('INSERT INTO error_log (project, file_path, error_type, line_number) VALUES (?, ?, ?, ?)')
                    .run('test-5', 'src/a.ts', 'null_check', 10);
            }
            db.prepare('INSERT INTO error_log (project, file_path, error_type, line_number) VALUES (?, ?, ?, ?)')
                .run('test-5', 'src/b.ts', 'n_plus_1', 5);
            const { getFailurePatterns } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const failures = getFailurePatterns({ language: 'test-5' });
            expect(failures.length).toBe(2);
            const nullCheck = failures.find(f => f.category === 'null_check');
            expect(nullCheck).toBeDefined();
            expect(nullCheck.frequency).toBe(3);
            expect(nullCheck.mitigation).toContain('optional chaining');
        });
    });
    describe('5.4: Benchmarks', () => {
        it('addBenchmark records value with delta', async () => {
            const { addBenchmark, getBenchmarks } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            addBenchmark({ metric: 'avg_file_size', value: 200, userValue: 150, category: 'code' });
            addBenchmark({ metric: 'test_coverage', value: 0.7, userValue: 0.85, category: 'quality' });
            const benchmarks = getBenchmarks();
            expect(benchmarks.length).toBe(2);
            const coverage = benchmarks.find(b => b.metric === 'test_coverage');
            expect(coverage.userValue).toBe(0.85);
            expect(coverage.delta).toBeCloseTo(0.15, 5);
        });
    });
    describe('5.5: Tech evolution', () => {
        it('classifies tech by signal count and score', async () => {
            const { getDb } = require('../walls/06-memory/database/database');
            const db = getDb();
            db.prepare('INSERT INTO tech_proficiency (project, technology, signals_count, proficiency_score) VALUES (?, ?, ?, ?)')
                .run('test-evo', 'TypeScript', 200, 90);
            db.prepare('INSERT INTO tech_proficiency (project, technology, signals_count, proficiency_score) VALUES (?, ?, ?, ?)')
                .run('test-evo', 'NewLang', 3, 30);
            const { getTechEvolution } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const evo = getTechEvolution();
            const ts = evo.find(e => e.technology === 'TypeScript');
            const nl = evo.find(e => e.technology === 'NewLang');
            expect(ts.adoptionPhase).toBe('mature');
            expect(nl.adoptionPhase).toBe('emerging');
        });
    });
    describe('5.6: Aggregated stats', () => {
        it('returns total counts and by-category breakdown', async () => {
            const { shareCommunityPattern, getCommunityStats } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            shareCommunityPattern({ category: 'naming_style', rule: 'camelCase', language: 'typescript' });
            shareCommunityPattern({ category: 'naming_style', rule: 'snake_case', language: 'python' });
            shareCommunityPattern({ category: 'error_handling', rule: 'try-catch', language: 'typescript' });
            const { addCommunityInsight } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            addCommunityInsight({ type: 'failure', title: 'Null check missing', description: 'X', category: 'naming', language: 'typescript', severity: 'critical', evidence: '' });
            const stats = getCommunityStats();
            expect(stats.totalPatterns).toBe(3);
            expect(stats.totalInsights).toBe(1);
            expect(stats.byCategory['naming_style']).toBe(2);
            expect(stats.byCategory['error_handling']).toBe(1);
            expect(stats.byLanguage['typescript']).toBe(2);
        });
    });
    describe('Anonymous ID', () => {
        it('createAnonymousId returns 16-char hash', async () => {
            const { createAnonymousId } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const id = createAnonymousId();
            expect(id).toHaveLength(16);
            expect(id).toMatch(/^[a-f0-9]+$/);
        });
        it('different calls return different IDs', async () => {
            const { createAnonymousId } = await Promise.resolve().then(() => __importStar(require('../walls/06-memory/stores/community-store')));
            const a = createAnonymousId();
            const b = createAnonymousId();
            expect(a).not.toBe(b);
        });
    });
});
//# sourceMappingURL=community-store.test.js.map