import type { PermissionAction, PermissionRule } from './types.js';
import { parseBashCommand, parseCommandSimple, type ParsedCommand } from './bash-parser.js';

/**
 * 将通配符模式转换为正则表达式
 * 支持 * 匹配任意字符
 */
function patternToRegex(pattern: string): RegExp {
  const escaped = pattern
    .replace(/[.+^${}()|[\]\\]/g, '\\$&')  // 转义特殊字符
    .replace(/\*/g, '.*')                   // * -> .*
    .replace(/\?/g, '.');                   // ? -> .
  return new RegExp(`^${escaped}$`, 'i');
}

/**
 * 检查命令是否匹配模式
 */
export function matchPattern(command: string, pattern: string): boolean {
  const regex = patternToRegex(pattern);
  return regex.test(command);
}

/**
 * 从命令中提取命令名和子命令（简单版本，用于向后兼容）
 */
export function parseCommand(command: string): { head: string; sub?: string; args: string[] } {
  const parsed = parseCommandSimple(command);
  return {
    head: parsed.name,
    sub: parsed.subcommand,
    args: parsed.args,
  };
}

/**
 * 生成用于权限请求的模式
 * 例如: "git push origin" -> "git push *"
 */
export function generateAskPattern(command: string): string {
  const parsed = parseCommandSimple(command);
  if (parsed.subcommand) {
    return `${parsed.name} ${parsed.subcommand} *`;
  }
  return `${parsed.name} *`;
}

/**
 * 生成用于权限请求的模式（从 ParsedCommand）
 */
export function generateAskPatternFromParsed(parsed: ParsedCommand): string {
  if (parsed.subcommand) {
    return `${parsed.name} ${parsed.subcommand} *`;
  }
  return `${parsed.name} *`;
}

/**
 * 检查单个命令是否匹配规则
 */
function matchSingleCommand(
  parsed: ParsedCommand,
  rules: PermissionRule[],
  defaultAction: PermissionAction
): { action: PermissionAction; matchedPattern?: string } {
  // 构建可能的匹配字符串
  const candidates = [
    parsed.text,                                              // 完整命令
    parsed.subcommand
      ? `${parsed.name} ${parsed.subcommand}`
      : parsed.name,                                          // 命令 + 子命令
    parsed.name,                                              // 仅命令名
  ];

  for (const rule of rules) {
    for (const candidate of candidates) {
      if (matchPattern(candidate, rule.pattern)) {
        return { action: rule.action, matchedPattern: rule.pattern };
      }
    }
  }

  return { action: defaultAction };
}

/**
 * 检查命令是否匹配规则列表，返回对应的动作（同步版本，使用简单解析）
 */
export function matchRules(
  command: string,
  rules: PermissionRule[],
  defaultAction: PermissionAction
): { action: PermissionAction; matchedPattern?: string } {
  const parsed = parseCommandSimple(command);
  return matchSingleCommand(parsed, rules, defaultAction);
}

/**
 * 检查原始命令字符串是否包含危险的重定向操作
 * 这是一个快速预检，在 tree-sitter 解析之前进行
 */
function checkRedirectInRawCommand(
  command: string,
  rules: PermissionRule[]
): { action: PermissionAction; matchedPattern?: string } | null {
  // 检查重定向相关的 deny 规则
  const redirectPatterns = ['* > *', '* >> *', '* << *'];

  for (const rule of rules) {
    if (rule.action === 'deny' && redirectPatterns.includes(rule.pattern)) {
      // 根据模式检查原始命令
      if (rule.pattern === '* > *' && / > /.test(command) && !/ >> /.test(command)) {
        return { action: 'deny', matchedPattern: rule.pattern };
      }
      if (rule.pattern === '* >> *' && / >> /.test(command)) {
        return { action: 'deny', matchedPattern: rule.pattern };
      }
      if (rule.pattern === '* << *' && / << /.test(command)) {
        return { action: 'deny', matchedPattern: rule.pattern };
      }
    }
  }

  return null;
}

/**
 * 使用 tree-sitter 解析并检查所有命令的权限（异步版本）
 * 返回最严格的权限要求
 */
export async function matchRulesAsync(
  command: string,
  rules: PermissionRule[],
  defaultAction: PermissionAction
): Promise<{
  action: PermissionAction;
  matchedPattern?: string;
  allCommands: ParsedCommand[];
  askPatterns: string[];
}> {
  // 首先检查原始命令中的重定向操作（这是安全关键检查，必须在解析之前进行）
  const redirectCheck = checkRedirectInRawCommand(command, rules);
  if (redirectCheck) {
    // 如果检测到重定向被拒绝，直接返回
    return {
      action: redirectCheck.action,
      matchedPattern: redirectCheck.matchedPattern,
      allCommands: [parseCommandSimple(command)],
      askPatterns: [],
    };
  }

  const result = await parseBashCommand(command);

  // 如果解析失败，降级到简单解析
  if (!result.success || result.commands.length === 0) {
    const parsed = parseCommandSimple(command);
    const match = matchSingleCommand(parsed, rules, defaultAction);
    return {
      ...match,
      allCommands: [parsed],
      askPatterns: match.action === 'ask' ? [generateAskPatternFromParsed(parsed)] : [],
    };
  }

  // 检查所有命令，收集结果
  let finalAction: PermissionAction = 'allow';
  let finalPattern: string | undefined;
  const askPatterns: string[] = [];

  for (const parsed of result.commands) {
    // 跳过 cd 命令（如果通过了外部目录检查）
    if (parsed.name === 'cd') {
      continue;
    }

    const match = matchSingleCommand(parsed, rules, defaultAction);

    // 权限优先级: deny > ask > allow
    if (match.action === 'deny') {
      finalAction = 'deny';
      finalPattern = match.matchedPattern;
      break; // deny 直接终止
    } else if (match.action === 'ask' && finalAction === 'allow') {
      finalAction = 'ask';
      finalPattern = match.matchedPattern;
      askPatterns.push(generateAskPatternFromParsed(parsed));
    }
    // allow 不改变已有的更严格权限
  }

  return {
    action: finalAction,
    matchedPattern: finalPattern,
    allCommands: result.commands,
    askPatterns: [...new Set(askPatterns)], // 去重
  };
}
