/**
 * SQL Sanitizer - The Last Line of Defense
 * Validates raw SQL before execution to prevent catastrophic accidents
 */

export interface SanitizationResult {
    safe: boolean;
    warnings: string[];
    blocked?: string;
}

// Dangerous patterns that should NEVER be allowed
const BLOCKED_PATTERNS = [
    /DROP\s+DATABASE/i,
    /DROP\s+SCHEMA/i,
    /ALTER\s+USER/i,
    /ALTER\s+ROLE/i,
    /CREATE\s+USER/i,
    /CREATE\s+ROLE/i,
    /GRANT\s+.*\s+TO/i,
    /REVOKE\s+.*\s+FROM/i,
];

// Patterns that require special attention
const WARNING_PATTERNS = [
    { pattern: /TRUNCATE/i, message: 'TRUNCATE detected - use with caution' },
    { pattern: /DROP\s+TABLE/i, message: 'DROP TABLE detected - irreversible' },
    { pattern: /DELETE\s+FROM\s+\w+\s*;/i, message: 'DELETE without WHERE clause - will delete ALL rows' },
    { pattern: /UPDATE\s+\w+\s+SET\s+.*\s*;/i, message: 'UPDATE without WHERE clause - will update ALL rows' },
];

/**
 * Validate table name is safe (alphanumeric + underscores only)
 */
export function validateTableName(tableName: string): boolean {
    return /^[a-zA-Z0-9_]+$/.test(tableName);
}

/**
 * Sanitize raw SQL before execution
 */
export function sanitizeSQL(sql: string): SanitizationResult {
    const trimmed = sql.trim();
    const warnings: string[] = [];

    // Check for blocked patterns
    for (const pattern of BLOCKED_PATTERNS) {
        if (pattern.test(trimmed)) {
            return {
                safe: false,
                warnings: [],
                blocked: `Blocked dangerous command: ${pattern.source}`
            };
        }
    }

    // Check for warning patterns
    for (const { pattern, message } of WARNING_PATTERNS) {
        if (pattern.test(trimmed)) {
            warnings.push(message);
        }
    }

    // Validate table names in common operations
    const tableMatches = trimmed.match(/(?:FROM|INTO|UPDATE|TRUNCATE|DROP TABLE)\s+([a-zA-Z0-9_]+)/gi);
    if (tableMatches) {
        for (const match of tableMatches) {
            const tableName = match.split(/\s+/).pop() || '';
            if (!validateTableName(tableName)) {
                return {
                    safe: false,
                    warnings: [],
                    blocked: `Invalid table name: ${tableName}`
                };
            }
        }
    }

    return {
        safe: true,
        warnings
    };
}

/**
 * Extract table names from SQL query
 */
export function extractTableNames(sql: string): string[] {
    const matches = sql.match(/(?:FROM|INTO|UPDATE|TRUNCATE|DROP TABLE)\s+([a-zA-Z0-9_]+)/gi);
    if (!matches) return [];

    return matches.map(m => m.split(/\s+/).pop() || '').filter(Boolean);
}

/**
 * Check if SQL contains WHERE clause
 */
export function hasWhereClause(sql: string): boolean {
    return /WHERE\s+/i.test(sql);
}

/**
 * More permissive check for maintenance window
 * Used when run_mechanic flag is set
 */
export function sanitizeSQLForMaintenance(sql: string): SanitizationResult {
    const trimmed = sql.trim();
    const warnings: string[] = [];

    // Still block the most dangerous commands
    const criticalPatterns = [
        /DROP\s+DATABASE/i,
        /DROP\s+SCHEMA/i,
        /ALTER\s+USER/i,
        /CREATE\s+USER/i,
    ];

    for (const pattern of criticalPatterns) {
        if (pattern.test(trimmed)) {
            return {
                safe: false,
                warnings: [],
                blocked: `Blocked critical command even in maintenance mode: ${pattern.source}`
            };
        }
    }

    // Allow TRUNCATE and DROP TABLE in maintenance mode
    warnings.push('Maintenance mode: dangerous operations allowed');

    return {
        safe: true,
        warnings
    };
}
