/**
 * Database Integration Layer
 *
 * Provides a unified interface for integrating the SQLite database
 * with existing components. This module bridges the old JSON-based
 * storage with the new database system.
 */
import { EventEmitter } from 'events';
// Import directly from source modules to avoid circular dependency with index.ts
import { initializeDatabase, getDatabaseManager } from './database-manager.js';
import { needsMigration, runMigration } from './migration.js';
import { getMemoryRepository } from './repositories/memory-repository.js';
import { getSessionRepository } from './repositories/session-repository.js';
import { getEmbeddingRepository } from './repositories/embedding-repository.js';
import { getCacheRepository } from './repositories/cache-repository.js';
import { initializeEmbeddingProvider, getEmbeddingProvider } from '../embeddings/index.js';
import { getPersistentLearning } from '../learning/index.js';
import { getPersistentAnalytics } from '../analytics/index.js';
// ============================================================================
// Database Integration Class
// ============================================================================
export class DatabaseIntegration extends EventEmitter {
    initialized = false;
    config;
    constructor(config = {}) {
        super();
        this.config = config;
    }
    /**
     * Initialize the database system
     */
    async initialize() {
        if (this.initialized)
            return;
        // Initialize database
        await initializeDatabase({
            dbPath: this.config.dbPath,
            inMemory: this.config.inMemory,
        });
        // Check for and run migration if needed
        if (this.config.autoMigrate !== false && needsMigration()) {
            this.emit('migration:starting');
            const result = await runMigration({ verbose: false });
            this.emit('migration:complete', result);
        }
        // Initialize embedding provider (will fall back to mock if local fails)
        try {
            await initializeEmbeddingProvider({
                provider: this.config.embeddingProvider || 'local',
            });
        }
        catch {
            // Continue without embeddings - mock will be used
            this.emit('warning', { type: 'embeddings', message: 'Using mock embeddings' });
        }
        this.initialized = true;
        this.emit('initialized');
    }
    /**
     * Check if initialized
     */
    isInitialized() {
        return this.initialized;
    }
    // ============================================================================
    // Memory Operations
    // ============================================================================
    /**
     * Add a memory
     */
    async addMemory(content, options) {
        const memoryRepo = getMemoryRepository();
        const embeddingProvider = getEmbeddingProvider();
        // Generate embedding if requested
        let embedding;
        if (options.generateEmbedding !== false) {
            try {
                const result = await embeddingProvider.embed(content);
                embedding = result.embedding;
            }
            catch {
                // Continue without embedding
            }
        }
        return memoryRepo.create({
            id: this.generateId(),
            type: options.type,
            scope: options.scope || 'user',
            project_id: options.projectId,
            content,
            embedding,
            importance: options.importance || 0.5,
            expires_at: options.expiresAt?.toISOString(),
            metadata: options.metadata,
        });
    }
    /**
     * Search memories
     */
    async searchMemories(query, options = {}) {
        const memoryRepo = getMemoryRepository();
        if (options.semantic) {
            // Semantic search using embeddings
            const embeddingProvider = getEmbeddingProvider();
            const queryResult = await embeddingProvider.embed(query);
            const filter = {
                type: options.type,
                scope: options.scope,
                projectId: options.projectId,
                minImportance: options.minImportance,
            };
            const results = memoryRepo.searchSimilar(queryResult.embedding, filter, options.limit || 10);
            return results.map(r => ({ memory: r.memory, similarity: r.similarity }));
        }
        else {
            // Keyword search
            const filter = {
                type: options.type,
                scope: options.scope,
                projectId: options.projectId,
                minImportance: options.minImportance,
                limit: options.limit,
            };
            const memories = memoryRepo.find(filter);
            // Simple keyword matching
            const queryLower = query.toLowerCase();
            return memories
                .filter(m => m.content.toLowerCase().includes(queryLower))
                .map(m => ({ memory: m }));
        }
    }
    /**
     * Get memories by filter
     */
    getMemories(filter = {}) {
        return getMemoryRepository().find(filter);
    }
    /**
     * Update memory importance
     */
    updateMemoryImportance(id, importance) {
        return getMemoryRepository().update(id, { importance });
    }
    /**
     * Delete memory
     */
    deleteMemory(id) {
        return getMemoryRepository().delete(id);
    }
    // ============================================================================
    // Session Operations
    // ============================================================================
    /**
     * Create a new session
     */
    createSession(options = {}) {
        const sessionRepo = getSessionRepository();
        const analytics = getPersistentAnalytics();
        // Record session in analytics
        analytics.recordSession(options.projectId);
        return sessionRepo.createSession({
            id: this.generateId(),
            project_id: options.projectId,
            project_path: options.projectPath,
            name: options.name,
            model: options.model,
        });
    }
    /**
     * Get session by ID
     */
    getSession(id) {
        return getSessionRepository().getSessionById(id);
    }
    /**
     * Add message to session
     */
    addMessage(sessionId, role, content, options = {}) {
        return getSessionRepository().addMessage({
            session_id: sessionId,
            role,
            content,
            tool_calls: options.toolCalls,
            tool_call_id: options.toolCallId,
            tokens: options.tokens,
        });
    }
    /**
     * Get messages for session
     */
    getMessages(sessionId, limit) {
        return getSessionRepository().getMessages(sessionId, limit);
    }
    /**
     * Update session stats
     */
    updateSessionStats(sessionId, stats) {
        getSessionRepository().updateSessionStats(sessionId, stats);
        // Also record in analytics
        if (stats.tokensIn || stats.tokensOut || stats.cost) {
            const session = this.getSession(sessionId);
            const analytics = getPersistentAnalytics();
            analytics.record({
                model: session?.model || 'unknown',
                tokensIn: stats.tokensIn || 0,
                tokensOut: stats.tokensOut || 0,
                cost: stats.cost || 0,
                responseTimeMs: 0,
                cacheHit: false,
                toolCalls: stats.toolCalls,
                projectId: session?.project_id,
            });
        }
    }
    /**
     * Get recent sessions
     */
    getRecentSessions(limit = 10) {
        return getSessionRepository().findSessions({ limit, isArchived: false });
    }
    // ============================================================================
    // Learning Operations
    // ============================================================================
    /**
     * Record repair attempt
     */
    recordRepairAttempt(errorMessage, errorType, strategy, success, attempts, options = {}) {
        const learning = getPersistentLearning();
        learning.recordRepairAttempt({
            errorMessage,
            errorType,
            strategy,
            success,
            attempts,
            ...options,
        });
    }
    /**
     * Get best repair strategies
     */
    getBestRepairStrategies(errorMessage, options = {}) {
        const learning = getPersistentLearning();
        const strategies = learning.getBestRepairStrategies(errorMessage, options);
        return strategies.map(s => ({
            strategy: s.strategy,
            successRate: s.success_rate,
        }));
    }
    /**
     * Record tool usage
     */
    recordToolUsage(toolName, success, timeMs, cacheHit, projectId) {
        const learning = getPersistentLearning();
        learning.recordToolUsage({ toolName, success, timeMs, cacheHit, projectId });
    }
    // ============================================================================
    // Analytics Operations
    // ============================================================================
    /**
     * Get cost summary
     */
    getCostSummary() {
        const analytics = getPersistentAnalytics();
        return {
            session: analytics.getSessionCost(),
            daily: analytics.getDailyCost(),
            weekly: analytics.getWeeklyCost(),
            monthly: analytics.getMonthlyCost(),
        };
    }
    /**
     * Get analytics dashboard
     */
    getAnalyticsDashboard() {
        return getPersistentAnalytics().formatDashboard();
    }
    /**
     * Get learning stats
     */
    getLearningStats() {
        return getPersistentLearning().formatStats();
    }
    // ============================================================================
    // Cache Operations
    // ============================================================================
    /**
     * Get cached value
     */
    getCached(key) {
        return getCacheRepository().get(key);
    }
    /**
     * Set cached value
     */
    setCached(key, value, ttlMs) {
        getCacheRepository().set(key, value, { ttlMs });
    }
    /**
     * Get or compute cached value
     */
    async getOrComputeCached(key, computeFn, ttlMs) {
        const result = await getCacheRepository().getOrCompute(key, computeFn, { ttlMs });
        return result.value;
    }
    // ============================================================================
    // Code Embedding Operations
    // ============================================================================
    /**
     * Index code chunk
     */
    async indexCodeChunk(projectId, filePath, chunkIndex, chunkText, options = {}) {
        const embeddingRepo = getEmbeddingRepository();
        const embeddingProvider = getEmbeddingProvider();
        // Generate embedding
        const result = await embeddingProvider.embed(chunkText);
        // Create hash for change detection
        const hash = this.hashString(chunkText);
        embeddingRepo.upsert({
            project_id: projectId,
            file_path: filePath,
            chunk_index: chunkIndex,
            chunk_text: chunkText,
            chunk_hash: hash,
            embedding: result.embedding,
            ...options,
        });
    }
    /**
     * Search code semantically
     */
    async searchCode(query, projectId, options = {}) {
        const embeddingRepo = getEmbeddingRepository();
        const embeddingProvider = getEmbeddingProvider();
        const queryResult = await embeddingProvider.embed(query);
        const results = embeddingRepo.searchSimilar(queryResult.embedding, { projectId, symbolType: options.symbolType }, options.limit || 10);
        return results.map(r => ({
            filePath: r.embedding.file_path,
            chunkText: r.embedding.chunk_text,
            similarity: r.similarity,
        }));
    }
    // ============================================================================
    // Database Stats
    // ============================================================================
    /**
     * Get database statistics
     */
    getStats() {
        return {
            database: getDatabaseManager().getStats(),
            memory: getMemoryRepository().getStats(),
            session: getSessionRepository().getStats(),
            embedding: getEmbeddingRepository().getStats(),
            cache: getCacheRepository().getStats(),
        };
    }
    /**
     * Format stats for display
     */
    formatStats() {
        return getDatabaseManager().formatStats();
    }
    // ============================================================================
    // Utility Methods
    // ============================================================================
    generateId() {
        return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    }
    hashString(str) {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash;
        }
        return Math.abs(hash).toString(36);
    }
}
// ============================================================================
// Singleton Instance
// ============================================================================
let instance = null;
export function getDatabaseIntegration(config) {
    if (!instance) {
        instance = new DatabaseIntegration(config);
    }
    return instance;
}
export async function initializeDatabaseIntegration(config) {
    const integration = getDatabaseIntegration(config);
    if (!integration.isInitialized()) {
        await integration.initialize();
    }
    return integration;
}
export function resetDatabaseIntegration() {
    instance = null;
}
//# sourceMappingURL=integration.js.map