"use strict";
/**
 * Graceful Degradation Framework
 * Provides intelligent fallback strategies for analysis failures
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.globalDegradationEngine = exports.GracefulDegradationEngine = exports.DegradationLevel = void 0;
const logger_1 = require("../utils/logger");
var DegradationLevel;
(function (DegradationLevel) {
    DegradationLevel[DegradationLevel["NONE"] = 0] = "NONE";
    DegradationLevel[DegradationLevel["MINIMAL"] = 1] = "MINIMAL";
    DegradationLevel[DegradationLevel["MODERATE"] = 2] = "MODERATE";
    DegradationLevel[DegradationLevel["AGGRESSIVE"] = 3] = "AGGRESSIVE";
    DegradationLevel[DegradationLevel["EMERGENCY"] = 4] = "EMERGENCY";
})(DegradationLevel || (exports.DegradationLevel = DegradationLevel = {}));
/**
 * Main Graceful Degradation Engine
 */
class GracefulDegradationEngine {
    strategies = new Map();
    currentLevel = DegradationLevel.NONE;
    appliedStrategies = [];
    constructor() {
        this.initializeDefaultStrategies();
    }
    /**
     * Evaluate context and determine appropriate degradation level
     */
    assessDegradationNeeds(context) {
        logger_1.logger.debug('Assessing degradation needs', { context });
        // Check memory pressure
        if (context.availableMemoryMB < 100) {
            return DegradationLevel.EMERGENCY;
        }
        if (context.availableMemoryMB < 256) {
            return DegradationLevel.AGGRESSIVE;
        }
        if (context.availableMemoryMB < 512) {
            return DegradationLevel.MODERATE;
        }
        // Check processing time
        if (context.processingTimeMs > 300000) {
            // 5 minutes
            return DegradationLevel.MODERATE;
        }
        // Check error history
        if (context.errorHistory.length > 10) {
            return DegradationLevel.AGGRESSIVE;
        }
        if (context.errorHistory.length > 5) {
            return DegradationLevel.MODERATE;
        }
        // Check data quality
        if (context.dataQualityScore < 30) {
            return DegradationLevel.MODERATE;
        }
        if (context.dataQualityScore < 50) {
            return DegradationLevel.MINIMAL;
        }
        return DegradationLevel.NONE;
    }
    /**
     * Apply degradation strategies based on context
     */
    applyDegradation(context, analysisFunction) {
        return this.executeWithDegradation(context, analysisFunction);
    }
    /**
     * Execute analysis with progressive degradation
     */
    async executeWithDegradation(context, analysisFunction) {
        const targetLevel = this.assessDegradationNeeds(context);
        this.currentLevel = targetLevel;
        this.appliedStrategies = [];
        logger_1.logger.info(`Applying degradation level: ${DegradationLevel[targetLevel]}`);
        try {
            // Apply pre-analysis degradation strategies
            this.applyPreAnalysisStrategies(targetLevel, context);
            // Attempt analysis with current strategies
            const result = await this.attemptAnalysisWithFallbacks(analysisFunction, context);
            return {
                result,
                degradationLevel: this.currentLevel,
                appliedStrategies: this.appliedStrategies,
                completedSections: this.getCompletedSections(result),
                failedSections: [],
                partialSections: this.getPartialSections(result),
                qualityRetained: this.calculateQualityRetention(),
                userGuidance: this.generateUserGuidance(),
                recoveryOptions: this.generateRecoveryOptions(context),
            };
        }
        catch (error) {
            logger_1.logger.error('Analysis failed with degradation', { error, level: this.currentLevel });
            return this.handleCompleteFailure(error, context);
        }
    }
    /**
     * Attempt analysis with progressive fallbacks
     */
    async attemptAnalysisWithFallbacks(analysisFunction, context) {
        const maxAttempts = 3;
        let currentAttempt = 0;
        let lastError = null;
        while (currentAttempt < maxAttempts) {
            try {
                logger_1.logger.debug(`Analysis attempt ${currentAttempt + 1}/${maxAttempts}`);
                const result = await analysisFunction();
                logger_1.logger.info(`Analysis succeeded on attempt ${currentAttempt + 1}`);
                return result;
            }
            catch (error) {
                lastError = error;
                currentAttempt++;
                logger_1.logger.warn(`Analysis attempt ${currentAttempt} failed`, { error });
                if (currentAttempt < maxAttempts) {
                    // Escalate degradation for next attempt
                    this.escalateDegradation(context);
                }
            }
        }
        // All attempts failed, return partial results if possible
        throw lastError || new Error('Analysis failed after all attempts');
    }
    /**
     * Apply strategies before analysis begins
     */
    applyPreAnalysisStrategies(level, context) {
        const strategies = this.getStrategiesForLevel(level);
        for (const strategy of strategies) {
            if (this.shouldApplyStrategy(strategy, context)) {
                this.applyStrategy(strategy);
                this.appliedStrategies.push(strategy);
            }
        }
    }
    /**
     * Check if strategy should be applied
     */
    shouldApplyStrategy(strategy, context) {
        const trigger = strategy.trigger;
        if (trigger.memoryThresholdMB && context.availableMemoryMB >= trigger.memoryThresholdMB) {
            return false;
        }
        if (trigger.processingTimeThresholdMs &&
            context.processingTimeMs < trigger.processingTimeThresholdMs) {
            return false;
        }
        if (trigger.errorCountThreshold && context.errorHistory.length < trigger.errorCountThreshold) {
            return false;
        }
        if (trigger.dataQualityThreshold && context.dataQualityScore >= trigger.dataQualityThreshold) {
            return false;
        }
        return true;
    }
    /**
     * Apply specific degradation strategy
     */
    applyStrategy(strategy) {
        logger_1.logger.info(`Applying degradation strategy: ${strategy.userMessage}`);
        for (const action of strategy.actions) {
            this.executeAction(action);
        }
    }
    /**
     * Execute degradation action
     */
    executeAction(action) {
        logger_1.logger.debug(`Executing degradation action: ${action.type} on ${action.target}`);
        switch (action.type) {
            case 'disable_feature':
                this.disableFeature(action.target);
                break;
            case 'reduce_scope':
                this.reduceScope(action.target, action.parameters);
                break;
            case 'simplify_algorithm':
                this.simplifyAlgorithm(action.target, action.parameters);
                break;
            case 'skip_optional':
                this.skipOptional(action.target);
                break;
            case 'use_sampling':
                this.enableSampling(action.target, action.parameters);
                break;
        }
    }
    /**
     * Escalate degradation level for retry
     */
    escalateDegradation(context) {
        if (this.currentLevel < DegradationLevel.EMERGENCY) {
            this.currentLevel++;
            logger_1.logger.info(`Escalating degradation to level: ${DegradationLevel[this.currentLevel]}`);
            this.applyPreAnalysisStrategies(this.currentLevel, context);
        }
    }
    /**
     * Handle complete analysis failure
     */
    handleCompleteFailure(error, context) {
        logger_1.logger.error('Complete analysis failure', { error: error.message });
        return {
            result: {},
            degradationLevel: DegradationLevel.EMERGENCY,
            appliedStrategies: this.appliedStrategies,
            completedSections: [],
            failedSections: ['all'],
            partialSections: [],
            qualityRetained: 0,
            userGuidance: 'Analysis failed completely. Please try with smaller data or reduced settings.',
            recoveryOptions: this.generateEmergencyRecoveryOptions(error, context),
        };
    }
    /**
     * Initialize default degradation strategies
     */
    initializeDefaultStrategies() {
        // Minimal degradation - reduce optional features
        this.strategies.set('minimal', {
            level: DegradationLevel.MINIMAL,
            trigger: { memoryThresholdMB: 512, dataQualityThreshold: 70 },
            actions: [
                {
                    type: 'skip_optional',
                    target: 'advanced_statistics',
                    impact: 'Some advanced statistical measures will be skipped',
                },
                {
                    type: 'reduce_scope',
                    target: 'correlation_analysis',
                    parameters: { maxPairs: 20 },
                    impact: 'Correlation analysis limited to top 20 pairs',
                },
            ],
            fallbackAnalyses: ['basic_statistics', 'data_quality'],
            qualityImpact: 10,
            userMessage: 'Using simplified analysis to optimize performance',
        });
        // Moderate degradation - significant scope reduction
        this.strategies.set('moderate', {
            level: DegradationLevel.MODERATE,
            trigger: { memoryThresholdMB: 256, errorCountThreshold: 5, dataQualityThreshold: 50 },
            actions: [
                {
                    type: 'disable_feature',
                    target: 'multivariate_analysis',
                    impact: 'Multivariate analysis disabled',
                },
                {
                    type: 'use_sampling',
                    target: 'large_datasets',
                    parameters: { sampleSize: 5000 },
                    impact: 'Analysis limited to 5,000 row sample',
                },
                {
                    type: 'simplify_algorithm',
                    target: 'clustering',
                    parameters: { algorithm: 'kmeans_simple' },
                    impact: 'Using simplified clustering algorithm',
                },
            ],
            fallbackAnalyses: ['univariate_analysis', 'basic_quality'],
            qualityImpact: 30,
            userMessage: 'Using reduced analysis scope due to resource constraints',
        });
        // Aggressive degradation - minimal analysis only
        this.strategies.set('aggressive', {
            level: DegradationLevel.AGGRESSIVE,
            trigger: { memoryThresholdMB: 128, errorCountThreshold: 10 },
            actions: [
                {
                    type: 'disable_feature',
                    target: 'visualization_recommendations',
                    impact: 'Visualization recommendations disabled',
                },
                {
                    type: 'disable_feature',
                    target: 'engineering_recommendations',
                    impact: 'Engineering recommendations disabled',
                },
                {
                    type: 'use_sampling',
                    target: 'all_analysis',
                    parameters: { sampleSize: 1000 },
                    impact: 'Analysis limited to 1,000 row sample',
                },
            ],
            fallbackAnalyses: ['basic_overview', 'simple_quality'],
            qualityImpact: 60,
            userMessage: 'Using minimal analysis due to severe resource constraints',
        });
        // Emergency degradation - absolute minimum
        this.strategies.set('emergency', {
            level: DegradationLevel.EMERGENCY,
            trigger: { memoryThresholdMB: 64 },
            actions: [
                {
                    type: 'disable_feature',
                    target: 'all_advanced_features',
                    impact: 'All advanced features disabled',
                },
                {
                    type: 'use_sampling',
                    target: 'emergency_sample',
                    parameters: { sampleSize: 100 },
                    impact: 'Analysis limited to 100 row sample',
                },
            ],
            fallbackAnalyses: ['file_overview_only'],
            qualityImpact: 90,
            userMessage: 'Emergency mode: providing minimal file overview only',
        });
    }
    // Helper methods for strategy application
    disableFeature(feature) {
        // Implementation would disable specific features
        logger_1.logger.debug(`Disabling feature: ${feature}`);
    }
    reduceScope(target, parameters) {
        // Implementation would reduce analysis scope
        logger_1.logger.debug(`Reducing scope for: ${target}`, { parameters });
    }
    simplifyAlgorithm(target, parameters) {
        // Implementation would use simpler algorithms
        logger_1.logger.debug(`Simplifying algorithm for: ${target}`, { parameters });
    }
    skipOptional(target) {
        // Implementation would skip optional analysis
        logger_1.logger.debug(`Skipping optional: ${target}`);
    }
    enableSampling(target, parameters) {
        // Implementation would enable data sampling
        logger_1.logger.debug(`Enabling sampling for: ${target}`, { parameters });
    }
    getStrategiesForLevel(level) {
        return Array.from(this.strategies.values()).filter((s) => s.level <= level);
    }
    getCompletedSections(result) {
        // Implementation would determine completed sections
        return Object.keys(result);
    }
    getPartialSections(result) {
        // Implementation would determine partial sections
        return [];
    }
    calculateQualityRetention() {
        const totalImpact = this.appliedStrategies.reduce((sum, s) => sum + s.qualityImpact, 0);
        return Math.max(0, 100 - totalImpact);
    }
    generateUserGuidance() {
        if (this.appliedStrategies.length === 0) {
            return 'Analysis completed successfully with full features.';
        }
        const messages = this.appliedStrategies.map((s) => s.userMessage);
        return `Analysis completed with adaptations: ${messages.join('; ')}.`;
    }
    generateRecoveryOptions(context) {
        const options = [];
        if (context.availableMemoryMB < 512) {
            options.push({
                description: 'Increase available memory or reduce dataset size',
                action: 'adjust_settings',
                command: 'datapilot --memory-limit 2GB',
                automated: false,
                estimatedTime: '2-5 minutes',
                successProbability: 80,
            });
        }
        if (this.currentLevel > DegradationLevel.MINIMAL) {
            options.push({
                description: 'Retry with reduced scope',
                action: 'retry',
                command: 'datapilot --scope basic',
                automated: true,
                estimatedTime: '1-2 minutes',
                successProbability: 90,
            });
        }
        return options;
    }
    generateEmergencyRecoveryOptions(error, context) {
        return [
            {
                description: 'Try with a smaller data sample',
                action: 'reduce_data',
                command: 'head -n 1000 your-file.csv > sample.csv && datapilot sample.csv',
                automated: false,
                estimatedTime: '30 seconds',
                successProbability: 95,
            },
            {
                description: 'Contact support with error details',
                action: 'contact_support',
                automated: false,
                estimatedTime: '24-48 hours',
                successProbability: 100,
            },
        ];
    }
}
exports.GracefulDegradationEngine = GracefulDegradationEngine;
// Global instance
exports.globalDegradationEngine = new GracefulDegradationEngine();
//# sourceMappingURL=graceful-degradation.js.map