import { CommandRiskLevel } from '../../domain/value-objects/command-risk-level.vo';

/**
 * Centralized risk pattern definitions for command classification.
 * Extracted from CommandRiskClassifier for reuse across the codebase
 * (e.g., risk-rules controller, hook handlers, standing-order validation).
 */

export interface RiskPattern {
  pattern: RegExp;
  level: CommandRiskLevel;
  description: string;
}

export const FORBIDDEN_PATTERNS: RiskPattern[] = [
  {
    pattern: /rm\s+-rf\s+\/(?!tmp)/i,
    level: CommandRiskLevel.FORBIDDEN,
    description: 'Recursive delete on root paths (excluding /tmp)',
  },
  {
    pattern: /mkfs/i,
    level: CommandRiskLevel.FORBIDDEN,
    description: 'Filesystem format commands',
  },
  {
    pattern: /dd\s+if=.*of=\/dev/i,
    level: CommandRiskLevel.FORBIDDEN,
    description: 'Raw device writes via dd',
  },
  {
    pattern: /:(){ :\|:& };:/,
    level: CommandRiskLevel.FORBIDDEN,
    description: 'Fork bomb',
  },
  {
    pattern: /chmod\s+-R\s+777\s+\//i,
    level: CommandRiskLevel.FORBIDDEN,
    description: 'Recursive chmod 777 on root',
  },
  {
    pattern: />\s*\/dev\/sd[a-z]/i,
    level: CommandRiskLevel.FORBIDDEN,
    description: 'Redirect to block device',
  },
];

export const HIGH_RISK_PATTERNS: RiskPattern[] = [
  {
    pattern: /systemctl\s+(stop|restart|disable)/i,
    level: CommandRiskLevel.HIGH_RISK,
    description: 'Service management (stop/restart/disable)',
  },
  {
    pattern: /service\s+\w+\s+(stop|restart)/i,
    level: CommandRiskLevel.HIGH_RISK,
    description: 'Legacy service management (stop/restart)',
  },
  {
    pattern: /docker\s+(rm|stop|kill)/i,
    level: CommandRiskLevel.HIGH_RISK,
    description: 'Destructive Docker commands',
  },
  {
    pattern: /kubectl\s+delete/i,
    level: CommandRiskLevel.HIGH_RISK,
    description: 'Kubernetes resource deletion',
  },
  {
    pattern: /DROP\s+(TABLE|DATABASE)/i,
    level: CommandRiskLevel.HIGH_RISK,
    description: 'SQL DROP statements',
  },
  {
    pattern: /rm\s+-rf/i,
    level: CommandRiskLevel.HIGH_RISK,
    description: 'Recursive force delete',
  },
  {
    pattern: /reboot/i,
    level: CommandRiskLevel.HIGH_RISK,
    description: 'System reboot',
  },
  {
    pattern: /shutdown/i,
    level: CommandRiskLevel.HIGH_RISK,
    description: 'System shutdown',
  },
];

export const LOW_RISK_WRITE_PATTERNS: RiskPattern[] = [
  {
    pattern: /echo\s+.*>/i,
    level: CommandRiskLevel.LOW_RISK_WRITE,
    description: 'Redirect output to file',
  },
  {
    pattern: /tee\s/i,
    level: CommandRiskLevel.LOW_RISK_WRITE,
    description: 'Tee command (write to file and stdout)',
  },
  {
    pattern: /sed\s+-i/i,
    level: CommandRiskLevel.LOW_RISK_WRITE,
    description: 'In-place sed edit',
  },
  {
    pattern: /mv\s/i,
    level: CommandRiskLevel.LOW_RISK_WRITE,
    description: 'Move/rename files',
  },
  {
    pattern: /cp\s/i,
    level: CommandRiskLevel.LOW_RISK_WRITE,
    description: 'Copy files',
  },
  {
    pattern: /mkdir/i,
    level: CommandRiskLevel.LOW_RISK_WRITE,
    description: 'Create directory',
  },
  {
    pattern: /touch/i,
    level: CommandRiskLevel.LOW_RISK_WRITE,
    description: 'Create/update file timestamp',
  },
  {
    pattern: /docker\s+(run|exec|build)/i,
    level: CommandRiskLevel.LOW_RISK_WRITE,
    description: 'Docker run/exec/build',
  },
  {
    pattern: /kubectl\s+(apply|create|scale)/i,
    level: CommandRiskLevel.LOW_RISK_WRITE,
    description: 'Kubernetes apply/create/scale',
  },
];

/**
 * All risk patterns ordered from most dangerous to least.
 */
export const ALL_RISK_PATTERNS: RiskPattern[] = [
  ...FORBIDDEN_PATTERNS,
  ...HIGH_RISK_PATTERNS,
  ...LOW_RISK_WRITE_PATTERNS,
];

/**
 * Classifies a command by checking it against all known risk patterns.
 * Returns the highest matching risk level, or READ_ONLY if no patterns match.
 */
export function classifyCommand(command: string): CommandRiskLevel {
  for (const { pattern, level } of FORBIDDEN_PATTERNS) {
    if (pattern.test(command)) return level;
  }
  for (const { pattern, level } of HIGH_RISK_PATTERNS) {
    if (pattern.test(command)) return level;
  }
  for (const { pattern, level } of LOW_RISK_WRITE_PATTERNS) {
    if (pattern.test(command)) return level;
  }
  return CommandRiskLevel.READ_ONLY;
}

/**
 * Returns the matching risk pattern for a command, or null if read-only.
 */
export function getMatchingPattern(command: string): RiskPattern | null {
  for (const riskPattern of ALL_RISK_PATTERNS) {
    if (riskPattern.pattern.test(command)) {
      return riskPattern;
    }
  }
  return null;
}
