/**
 * Error Patterns - Recovery strategies for common errors
 */

import { RECOVERY } from "../../shared/index.js";
import * as Toast from "../notification/toast.js";
import type { ErrorContext, RecoveryAction } from "./handler.js";

export interface ErrorPattern {
    pattern: RegExp | string;
    category: string;
    handler: (context: ErrorContext) => RecoveryAction;
}

/**
 * Error patterns and their recovery strategies
 */
export const errorPatterns: ErrorPattern[] = [
    // Rate limiting
    {
        pattern: /rate.?limit|too.?many.?requests|429/i,
        category: "rate_limit",
        handler: (ctx: ErrorContext): RecoveryAction => {
            const delay = RECOVERY.BASE_DELAY_MS * Math.pow(2, ctx.attempt);
            Toast.presets.warningRateLimited();
            return { type: "retry", delay, attempt: ctx.attempt + 1 };
        },
    },

    // Context overflow
    {
        pattern: /context.?length|token.?limit|maximum.?context/i,
        category: "context_overflow",
        handler: (): RecoveryAction => {
            Toast.presets.errorRecovery("Compacting context");
            return { type: "compact", reason: "Context limit reached" };
        },
    },

    // Network errors
    {
        pattern: /ECONNREFUSED|ETIMEDOUT|network|fetch.?failed/i,
        category: "network",
        handler: (ctx: ErrorContext): RecoveryAction => {
            if (ctx.attempt >= RECOVERY.MAX_ATTEMPTS) {
                return { type: "abort", reason: "Network unavailable after retries" };
            }
            return { type: "retry", delay: RECOVERY.BASE_DELAY_MS * (ctx.attempt + 1), attempt: ctx.attempt + 1 };
        },
    },

    // Session errors
    {
        pattern: /session.?not.?found|session.?expired/i,
        category: "session",
        handler: (): RecoveryAction => {
            return { type: "abort", reason: "Session no longer available" };
        },
    },

    // Tool errors
    {
        pattern: /tool.?not.?found|unknown.?tool/i,
        category: "tool",
        handler: (ctx: ErrorContext): RecoveryAction => {
            return { type: "escalate", to: "Reviewer", reason: `Unknown tool used by ${ctx.agent}` };
        },
    },

    // Parse errors
    {
        pattern: /parse.?error|invalid.?json|syntax.?error/i,
        category: "parse",
        handler: (ctx: ErrorContext): RecoveryAction => {
            if (ctx.attempt >= 2) {
                return { type: "skip", reason: "Persistent parse error" };
            }
            return { type: "retry", delay: 500, attempt: ctx.attempt + 1 };
        },
    },

    // Gibberish / hallucination
    {
        pattern: /gibberish|hallucination|mixed.?language/i,
        category: "gibberish",
        handler: (): RecoveryAction => {
            Toast.presets.errorRecovery("Retrying with clean context");
            return { type: "retry", delay: 1000, attempt: 1 };
        },
    },

    // LSP specific errors
    {
        pattern: /lsp.?diagnostics|tsc.?error|eslint.?error/i,
        category: "lsp",
        handler: (ctx: ErrorContext): RecoveryAction => {
            return { type: "retry", delay: 2000, attempt: ctx.attempt + 1, modifyPrompt: "Note: Previous attempt had LSP issues. Ensure code quality and consider simpler implementation." };
        },
    },

    // execution timeout
    {
        pattern: /execution.?timed.?out|timeout/i,
        category: "timeout",
        handler: (ctx: ErrorContext): RecoveryAction => {
            return { type: "retry", delay: 5000, attempt: ctx.attempt + 1, modifyPrompt: "Note: Previous attempt timed out. Break down the task into smaller sub-tasks if necessary." };
        },
    },
];
