/**
 * Validation for a new folder's name, shared by the New Folder dialog.
 *
 * Windows' rules are applied on every platform: a workspace synced to a
 * Windows machine cannot contain a path that machine is unable to create, so
 * letting a Linux or macOS user make one just moves the breakage downstream.
 */

// Refused by Windows whatever the extension: CON, CON.txt, con.anything.
const WINDOWS_DEVICE_NAMES = new Set([
  'con', 'prn', 'aux', 'nul',
  'com1', 'com2', 'com3', 'com4', 'com5', 'com6', 'com7', 'com8', 'com9',
  'lpt1', 'lpt2', 'lpt3', 'lpt4', 'lpt5', 'lpt6', 'lpt7', 'lpt8', 'lpt9',
]);

const ILLEGAL_CHARS = /[<>:"|?*/\\]/;

/**
 * Why `rawName` can't be a folder here, or null if it can.
 * `existing` is the set of names already in the target folder.
 */
export function folderNameError(rawName, existing = new Set()) {
  const name = String(rawName ?? '').trim();

  if (!name || name === '.' || name === '..') return 'Enter a folder name.';
  if (ILLEGAL_CHARS.test(name)) {
    return 'A folder name can\'t contain / \\ : * ? " < > or |.';
  }
  if (name.endsWith('.')) return 'A folder name can\'t end with a dot.';
  if (WINDOWS_DEVICE_NAMES.has(name.split('.')[0].toLowerCase())) {
    return `"${name}" is a reserved name on Windows.`;
  }
  if (existing.has(name)) return `An item named "${name}" already exists here.`;

  return null;
}
