"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DatabaseTestHelper = void 0;
/**
 * Helper utilities for managing database behavior in tests
 */
class DatabaseTestHelper {
    db;
    originalTriggers = new Map();
    constructor(db) {
        this.db = db;
    }
    /**
     * Disable timestamp update triggers to prevent unexpected timestamp updates
     * during tests that are sensitive to update counts.
     */
    disableTimestampTriggers() {
        const triggerNames = [
            'update_context_items_timestamp',
            'update_sessions_timestamp',
            'update_retention_policies_timestamp',
            'update_feature_flags_timestamp',
            'increment_sequence_update',
        ];
        for (const triggerName of triggerNames) {
            // Get the trigger definition before dropping it
            const triggerDef = this.db
                .prepare(`SELECT sql FROM sqlite_master WHERE type = 'trigger' AND name = ?`)
                .get(triggerName);
            if (triggerDef && triggerDef.sql) {
                this.originalTriggers.set(triggerName, triggerDef.sql);
                // Drop the trigger
                this.db.exec(`DROP TRIGGER IF EXISTS ${triggerName}`);
            }
        }
    }
    /**
     * Re-enable timestamp update triggers after tests
     */
    enableTimestampTriggers() {
        for (const [triggerName, sql] of this.originalTriggers) {
            if (sql) {
                try {
                    this.db.exec(sql);
                }
                catch (error) {
                    console.warn(`Failed to recreate trigger ${triggerName}:`, error);
                }
            }
        }
        this.originalTriggers.clear();
    }
    /**
     * Normalize timestamps for comparison in tests.
     * Sets all timestamps to a fixed value to avoid timestamp-based failures.
     */
    normalizeTimestamps(items) {
        const fixedTimestamp = '2024-01-01T00:00:00.000Z';
        return items.map(item => ({
            ...item,
            created_at: fixedTimestamp,
            updated_at: fixedTimestamp,
        }));
    }
    /**
     * Update an item without triggering timestamp updates.
     * Useful for tests that need to control timestamps precisely.
     */
    updateWithoutTimestamp(table, updates, where) {
        // Build the UPDATE statement
        const setClauses = Object.keys(updates)
            .map(key => `${key} = ?`)
            .join(', ');
        const whereClauses = Object.keys(where)
            .map(key => `${key} = ?`)
            .join(' AND ');
        const sql = `UPDATE ${table} SET ${setClauses} WHERE ${whereClauses}`;
        const values = [...Object.values(updates), ...Object.values(where)];
        // Temporarily disable triggers
        this.disableTimestampTriggers();
        try {
            this.db.prepare(sql).run(...values);
        }
        finally {
            // Re-enable triggers
            this.enableTimestampTriggers();
        }
    }
    /**
     * Get counts of items by their modification status
     * Useful for tests that check added vs modified items
     */
    getModificationCounts(sessionId, sinceTimestamp) {
        const added = this.db
            .prepare(`SELECT COUNT(*) as count FROM context_items 
         WHERE session_id = ? AND created_at > ?`)
            .get(sessionId, sinceTimestamp);
        const modified = this.db
            .prepare(`SELECT COUNT(*) as count FROM context_items 
         WHERE session_id = ? 
         AND created_at <= ? 
         AND updated_at > ?`)
            .get(sessionId, sinceTimestamp, sinceTimestamp);
        return {
            added: added.count,
            modified: modified.count,
        };
    }
    /**
     * Create a test item with controlled timestamps
     */
    createTestItem(params) {
        const { id, sessionId, key, value, createdAt = new Date().toISOString(), updatedAt = createdAt, category = null, priority = 'normal', channel = 'general', } = params;
        // Temporarily disable triggers to control timestamps
        this.disableTimestampTriggers();
        try {
            this.db
                .prepare(`INSERT INTO context_items 
           (id, session_id, key, value, category, priority, channel, created_at, updated_at) 
           VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
                .run(id, sessionId, key, value, category, priority, channel, createdAt, updatedAt);
        }
        finally {
            this.enableTimestampTriggers();
        }
    }
    /**
     * Helper to check if change tracking triggers are affecting counts
     */
    getChangeTrackingCount(sessionId, sinceSequence = 0) {
        try {
            const result = this.db
                .prepare(`SELECT COUNT(*) as count FROM context_changes 
           WHERE session_id = ? AND sequence_id > ?`)
                .get(sessionId, sinceSequence);
            return result.count;
        }
        catch {
            // Table might not exist in all test environments
            return 0;
        }
    }
    /**
     * Clear all change tracking data for a clean test state
     */
    clearChangeTracking(sessionId) {
        try {
            if (sessionId) {
                this.db.prepare('DELETE FROM context_changes WHERE session_id = ?').run(sessionId);
            }
            else {
                this.db.prepare('DELETE FROM context_changes').run();
            }
        }
        catch {
            // Table might not exist in all test environments
        }
    }
}
exports.DatabaseTestHelper = DatabaseTestHelper;
