/**
 * Checks if a string matches a single pattern.
 */
function matchesPattern(name: string, pattern: string): boolean {
  // Exact match
  if (pattern === name) return true;

  // Convert glob pattern to regex
  // ** matches any number of directories
  // * matches any characters except /
  // Escape special regex characters
  const regexStr = pattern
    .replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape special chars
    .replace(/\*\*/g, '__DOUBLE_STAR__')
    .replace(/\*/g, '[^/]*') // * matches anything except /
    .replace(/__DOUBLE_STAR__/g, '.*'); // ** matches anything including /

  // For patterns like **/.*, match anywhere in the path (including root level)
  if (pattern.startsWith('**/')) {
    // Extract the pattern after **/
    const patternAfterPrefix = pattern.substring(3);
    // Convert the suffix pattern to regex (handling the case where ** matches zero directories)
    const suffixRegexStr = patternAfterPrefix
      .replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape special chars
      .replace(/\*\*/g, '__DOUBLE_STAR__')
      .replace(/\*/g, '[^/]*') // * matches anything except /
      .replace(/__DOUBLE_STAR__/g, '.*'); // ** matches anything including /

    // Match either at root level (no /) or with path prefix (.*/)
    const regex = new RegExp(`^(.*/)?${suffixRegexStr}$`);
    return regex.test(name);
  }

  // For patterns like .*, match if name starts with the pattern (without *)
  if (pattern.endsWith('*') && !pattern.includes('/')) {
    const prefix = pattern.slice(0, -1);
    return name.startsWith(prefix);
  }

  // For other patterns, try full match
  try {
    const regex = new RegExp(`^${regexStr}$`);
    return regex.test(name);
  } catch {
    // If regex is invalid, fall back to exact match
    return pattern === name;
  }
}

/**
 * Checks if a string matches any of the given patterns.
 * Supports wildcards:
 * - Exact match: secret.txt
 * - Prefix wildcard: .* matches files starting with .
 * - Glob pattern:  matches files starting with . in any directory/subdirectory
 * - Single wildcard: *.log matches files ending with .log
 */
export function matchesAnyPattern(name: string, patterns: string[]): boolean {
  if (patterns.length === 0) return false;

  return patterns.some((pattern) => matchesPattern(name, pattern));
}
