import { assistantEntryHasThinkingContentBlock } from "./context-assistant-turns.js";
function copyDeletionTarget(target) {
    return target.kind === "entry"
        ? { kind: "entry", entryId: target.entryId }
        : { kind: "content_block", entryId: target.entryId, blockIndex: target.blockIndex };
}
export class ContextDeletionMemoryStore {
    constructor(transcript) {
        this.deletionTargets = [];
        this.callCount = 0;
        const entryIds = new Set();
        const blockKeys = new Set();
        this.entries = transcript.entries.map((entry) => {
            if (entryIds.has(entry.entryId)) {
                throw new Error(`Duplicate transcript entry id: ${entry.entryId}`);
            }
            entryIds.add(entry.entryId);
            return {
                entryId: entry.entryId,
                role: entry.role,
                protected: entry.protected,
                hasAssistantThinkingBlocks: assistantEntryHasThinkingContentBlock(entry),
                tokenEstimate: entry.tokenEstimate,
                text: entry.text,
            };
        });
        this.entriesById = new Map(this.entries.map((entry) => [entry.entryId, entry]));
        this.contentBlocks = transcript.entries.flatMap((entry, entryPosition) => {
            const hasAssistantThinkingBlocks = assistantEntryHasThinkingContentBlock(entry);
            return entry.contentBlocks.map((block) => {
                if (block.entryId !== entry.entryId) {
                    throw new Error(`Transcript content block ${block.entryId}:${block.blockIndex} does not belong to entry ${entry.entryId}`);
                }
                const blockKey = `${block.entryId}:${block.blockIndex}`;
                if (blockKeys.has(blockKey)) {
                    throw new Error(`Duplicate transcript content block: ${blockKey}`);
                }
                blockKeys.add(blockKey);
                return {
                    entryPosition,
                    entryId: block.entryId,
                    blockIndex: block.blockIndex,
                    role: entry.role,
                    type: block.type,
                    protected: block.protected,
                    hasAssistantThinkingBlocks,
                    tokenEstimate: block.tokenEstimate,
                    text: block.text,
                };
            });
        });
        this.contentBlockCountByEntryId = new Map();
        for (const block of this.contentBlocks) {
            this.contentBlockCountByEntryId.set(block.entryId, (this.contentBlockCountByEntryId.get(block.entryId) ?? 0) + 1);
        }
    }
    transaction(operation) {
        const snapshot = this.snapshot();
        try {
            return operation();
        }
        catch (error) {
            this.restore(snapshot);
            throw error;
        }
    }
    readTargets() {
        return this.deletionTargets.map(copyDeletionTarget);
    }
    replaceTargets(targets) {
        this.deletionTargets = targets.map(copyDeletionTarget);
    }
    listEntriesForGrep() {
        return this.entries.map((entry) => ({
            entry_id: entry.entryId,
            text: entry.text,
            is_protected: entry.protected ? 1 : 0,
            has_assistant_thinking_blocks: entry.hasAssistantThinkingBlocks ? 1 : 0,
        }));
    }
    listContentBlocksForGrep() {
        return [...this.contentBlocks]
            .sort((a, b) => a.entryPosition - b.entryPosition || a.blockIndex - b.blockIndex)
            .map((block) => ({
            entry_id: block.entryId,
            block_index: block.blockIndex,
            role: block.role,
            type: block.type,
            text: block.text,
            entry_protected: this.entriesById.get(block.entryId)?.protected ? 1 : 0,
            block_protected: block.protected ? 1 : 0,
            block_count: this.contentBlockCountByEntryId.get(block.entryId) ?? 0,
            has_assistant_thinking_blocks: block.hasAssistantThinkingBlocks ? 1 : 0,
        }));
    }
    getEntryForRead(entryId) {
        const entry = this.entriesById.get(entryId);
        if (!entry)
            return undefined;
        return {
            entry_id: entry.entryId,
            role: entry.role,
            is_protected: entry.protected ? 1 : 0,
            has_assistant_thinking_blocks: entry.hasAssistantThinkingBlocks ? 1 : 0,
            token_estimate: entry.tokenEstimate,
            text: entry.text,
        };
    }
    getContentBlockForRead(entryId, blockIndex) {
        const block = this.contentBlocks.find((candidate) => candidate.entryId === entryId && candidate.blockIndex === blockIndex);
        if (!block)
            return undefined;
        return {
            entry_id: block.entryId,
            block_index: block.blockIndex,
            role: block.role,
            type: block.type,
            token_estimate: block.tokenEstimate,
            text: block.text,
            entry_protected: this.entriesById.get(block.entryId)?.protected ? 1 : 0,
            block_protected: block.protected ? 1 : 0,
            block_count: this.contentBlockCountByEntryId.get(block.entryId) ?? 0,
            has_assistant_thinking_blocks: block.hasAssistantThinkingBlocks ? 1 : 0,
        };
    }
    getGrepScanTextLength(target) {
        const texts = target === "entry" ? this.entries : this.contentBlocks;
        return texts.reduce((sum, item) => sum + item.text.length, 0);
    }
    incrementCallCount() {
        this.callCount += 1;
        return this.callCount;
    }
    getCallCount() {
        return this.callCount;
    }
    setLastError(message) {
        this.lastError = message;
    }
    clearLastError() {
        this.lastError = undefined;
    }
    getLastError() {
        return this.lastError;
    }
    snapshot() {
        return {
            deletionTargets: this.readTargets(),
            callCount: this.callCount,
            ...(this.lastError === undefined ? {} : { lastError: this.lastError }),
        };
    }
    restore(snapshot) {
        this.deletionTargets = snapshot.deletionTargets.map(copyDeletionTarget);
        this.callCount = snapshot.callCount;
        this.lastError = snapshot.lastError;
    }
}
export function createContextDeletionStore(transcript) {
    return new ContextDeletionMemoryStore(transcript);
}
//# sourceMappingURL=context-deletion-store.js.map