"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventStore = void 0;
exports.buildEvent = buildEvent;
const crypto_1 = require("crypto");
const fs_1 = require("fs");
const path_1 = require("path");
function ensureDir(path) {
    (0, fs_1.mkdirSync)(path, { recursive: true });
}
class EventStore {
    projectRoot;
    config;
    processed = new Set();
    constructor(projectRoot, config) {
        this.projectRoot = projectRoot;
        this.config = config;
        this.loadProcessedIndex();
    }
    paths() {
        const s = this.config.storage;
        return {
            eventsDir: (0, path_1.resolve)(this.projectRoot, s.eventsDir),
            latestStatus: (0, path_1.resolve)(this.projectRoot, s.latestStatus),
            processedIndex: (0, path_1.resolve)(this.projectRoot, s.processedIndex),
            inboxDir: (0, path_1.resolve)(this.projectRoot, s.inboxDir),
            archiveDir: (0, path_1.resolve)(this.projectRoot, s.archiveDir),
        };
    }
    loadProcessedIndex() {
        const { processedIndex } = this.paths();
        if (!(0, fs_1.existsSync)(processedIndex))
            return;
        try {
            const data = JSON.parse((0, fs_1.readFileSync)(processedIndex, 'utf8'));
            for (const k of data.keys ?? [])
                this.processed.add(k);
        }
        catch {
            // fresh index on parse failure
        }
    }
    persistProcessedIndex() {
        const { processedIndex } = this.paths();
        ensureDir((0, path_1.dirname)(processedIndex));
        (0, fs_1.writeFileSync)(processedIndex, JSON.stringify({ keys: [...this.processed].slice(-50000) }, null, 2));
    }
    dedupeKey(source, payload) {
        return (0, crypto_1.createHash)('sha256').update(`${source}\n${payload}`).digest('hex');
    }
    isProcessed(key) {
        return this.processed.has(key);
    }
    saveEvent(event) {
        const { eventsDir, latestStatus } = this.paths();
        ensureDir(eventsDir);
        const eventPath = (0, path_1.join)(eventsDir, `${event.id}.json`);
        (0, fs_1.writeFileSync)(eventPath, JSON.stringify(event, null, 2));
        const status = {
            updatedAt: new Date().toISOString(),
            lastEventId: event.id,
            lastMatched: event.matched,
            lastMessageType: event.messageType,
            lastSource: event.source,
            matchCount: event.matches.length,
            outbound: event.outbound ?? null,
        };
        ensureDir((0, path_1.dirname)(latestStatus));
        (0, fs_1.writeFileSync)(latestStatus, JSON.stringify(status, null, 2));
        this.processed.add(event.dedupeKey);
        this.persistProcessedIndex();
        (0, fs_1.appendFileSync)((0, path_1.join)(eventsDir, '..', 'events.jsonl'), `${JSON.stringify({ id: event.id, at: event.receivedAt, matched: event.matched, type: event.messageType, source: event.source })}\n`);
    }
    inboxPath() {
        return this.paths().inboxDir;
    }
    archiveFile(fromPath) {
        const { archiveDir } = this.paths();
        ensureDir(archiveDir);
        const base = fromPath.split('/').pop() ?? (0, crypto_1.randomUUID)();
        (0, fs_1.renameSync)(fromPath, (0, path_1.join)(archiveDir, `${Date.now()}-${base}`));
    }
}
exports.EventStore = EventStore;
function buildEvent(source, parsed, format, messageType, matches, canonical, raw, dedupeKey) {
    return {
        id: (0, crypto_1.randomUUID)(),
        receivedAt: new Date().toISOString(),
        source,
        format,
        messageType,
        matched: matches.length > 0,
        matches,
        parsed,
        canonical,
        rawPreview: raw.slice(0, 2000),
        dedupeKey,
    };
}
//# sourceMappingURL=eventStore.js.map