/**
 * Service Container - Dependency Injection
 *
 * Replaces the Service Locator pattern with a centralized container
 * that manages all core service instances.
 *
 * Benefits:
 * - Explicit dependencies (no hidden singletons)
 * - Easier testing (inject mocks)
 * - Single point of initialization
 * - Type-safe service access
 */
import { EventEmitter } from 'events';
// Runtime imports for service creation (ESM compatible)
import { getSettingsManager } from '../utils/settings-manager.js';
import { getCheckpointManager } from '../checkpoints/checkpoint-manager.js';
import { getSessionStore } from '../persistence/session-store.js';
import { getCostTracker } from '../utils/cost-tracker.js';
// ============================================================================
// Service Container Implementation
// ============================================================================
/**
 * ServiceContainer - Central registry for all application services
 *
 * Usage:
 * ```typescript
 * // Get the container
 * const container = ServiceContainer.create();
 *
 * // Access services
 * const settings = container.settings;
 * const checkpoints = container.checkpoints;
 *
 * // For testing, inject mocks
 * const testContainer = ServiceContainer.createWithConfig({
 *   settings: mockSettingsManager,
 *   checkpoints: mockCheckpointManager,
 * });
 * ```
 */
export class ServiceContainer {
    settings;
    checkpoints;
    sessions;
    costs;
    static instance = null;
    /**
     * Private constructor - use static factory methods
     */
    constructor(settings, checkpoints, sessions, costs) {
        this.settings = settings;
        this.checkpoints = checkpoints;
        this.sessions = sessions;
        this.costs = costs;
    }
    /**
     * Create or get the singleton ServiceContainer instance
     * Uses lazy initialization to load services on demand
     */
    static create() {
        if (!ServiceContainer.instance) {
            ServiceContainer.instance = ServiceContainer.createDefault();
        }
        return ServiceContainer.instance;
    }
    /**
     * Create a ServiceContainer with custom configuration
     * Useful for testing or custom service implementations
     */
    static createWithConfig(config) {
        return new ServiceContainer(config.settings ?? ServiceContainer.createSettingsManager(), config.checkpoints ?? ServiceContainer.createCheckpointManager(), config.sessions ?? ServiceContainer.createSessionStore(), config.costs ?? ServiceContainer.createCostTracker());
    }
    /**
     * Create a fresh ServiceContainer with default services
     * Does not affect the singleton instance
     */
    static createDefault() {
        return new ServiceContainer(ServiceContainer.createSettingsManager(), ServiceContainer.createCheckpointManager(), ServiceContainer.createSessionStore(), ServiceContainer.createCostTracker());
    }
    /**
     * Reset the singleton instance
     * Useful for testing or reinitializing services
     */
    static reset() {
        ServiceContainer.instance = null;
    }
    /**
     * Check if singleton instance exists
     */
    static hasInstance() {
        return ServiceContainer.instance !== null;
    }
    /**
     * Set a custom container as the singleton
     * Useful for testing
     */
    static setInstance(container) {
        ServiceContainer.instance = container;
    }
    // ============================================================================
    // Factory Methods for Individual Services
    // ============================================================================
    /**
     * Create SettingsManager instance
     * Uses the existing singleton implementation for compatibility
     */
    static createSettingsManager() {
        return getSettingsManager();
    }
    /**
     * Create CheckpointManager instance
     * Note: Implementation may not have all interface methods
     */
    static createCheckpointManager() {
        return getCheckpointManager();
    }
    /**
     * Create SessionStore instance
     * Note: Implementation may not have all interface methods
     */
    static createSessionStore() {
        return getSessionStore();
    }
    /**
     * Create CostTracker instance
     */
    static createCostTracker() {
        return getCostTracker();
    }
}
// ============================================================================
// Compatibility Functions
// ============================================================================
/**
 * Get the ServiceContainer singleton
 * Convenience function for easier access
 */
export function getServiceContainer() {
    return ServiceContainer.create();
}
/**
 * Create a test container with mock services
 * @param mocks - Partial mock implementations
 */
export function createTestContainer(mocks = {}) {
    // Create minimal mock implementations for missing services
    const defaultMocks = {
        settings: mocks.settings ?? createMockSettingsManager(),
        checkpoints: mocks.checkpoints ?? createMockCheckpointManager(),
        sessions: mocks.sessions ?? createMockSessionStore(),
        costs: mocks.costs ?? createMockCostTracker(),
    };
    return ServiceContainer.createWithConfig(defaultMocks);
}
// ============================================================================
// Mock Factory Functions (for testing)
// ============================================================================
function createMockSettingsManager() {
    return {
        // User settings
        loadUserSettings: () => ({ model: 'grok-test' }),
        saveUserSettings: () => { },
        updateUserSetting: () => { },
        getUserSetting: () => undefined,
        // Project settings
        loadProjectSettings: () => ({ model: 'grok-test' }),
        saveProjectSettings: () => { },
        updateProjectSetting: () => { },
        getProjectSetting: () => undefined,
        // Convenience methods
        getCurrentModel: () => 'grok-test',
        setCurrentModel: () => { },
        getAvailableModels: () => ['grok-test'],
        getApiKey: () => 'test-api-key',
        getBaseURL: () => 'https://test.api.com',
    };
}
function createMockCheckpointManager() {
    const emitter = new EventEmitter();
    return Object.assign(emitter, {
        createCheckpoint: () => ({ id: 'test', timestamp: new Date(), description: '', files: [], workingDirectory: '' }),
        checkpointBeforeEdit: () => ({ id: 'test', timestamp: new Date(), description: '', files: [], workingDirectory: '' }),
        restoreCheckpoint: () => true,
        getCheckpoints: () => [],
        getCheckpoint: () => undefined,
        clearCheckpoints: () => { },
        clearOldCheckpoints: () => { },
        rewindToLast: () => ({ success: true, restored: [], errors: [] }),
        formatCheckpointList: () => 'No checkpoints',
    });
}
function createMockSessionStore() {
    return {
        createSession: (name, model) => ({
            id: 'test',
            name,
            workingDirectory: process.cwd(),
            model,
            messages: [],
            createdAt: new Date(),
            lastAccessedAt: new Date(),
        }),
        getCurrentSession: () => null,
        getCurrentSessionId: () => null,
        setCurrentSession: () => true,
        listSessions: () => [],
        getSession: () => null,
        deleteSession: () => true,
        addMessage: () => { },
        updateCurrentSession: () => { },
        formatSessionList: () => 'No sessions',
        exportSessionToFile: () => null,
    };
}
function createMockCostTracker() {
    const emitter = new EventEmitter();
    return Object.assign(emitter, {
        recordUsage: () => ({ inputTokens: 0, outputTokens: 0, model: 'test', timestamp: new Date(), cost: 0 }),
        calculateCost: () => 0,
        getReport: () => ({
            sessionCost: 0,
            dailyCost: 0,
            weeklyCost: 0,
            monthlyCost: 0,
            totalCost: 0,
            sessionTokens: { input: 0, output: 0 },
            modelBreakdown: {},
            recentUsage: [],
        }),
        resetSession: () => { },
        clearHistory: () => { },
        setBudgetLimit: () => { },
        setDailyLimit: () => { },
        exportToCsv: () => '',
        formatDashboard: () => '',
        dispose: () => { },
    });
}
//# sourceMappingURL=service-container.js.map