import { MenuUrlSchemeError } from './errors.js'

const ALLOWED_SCHEMES = new Set(['http', 'https', 'mailto'])

/**
 * Accept http/https/mailto/path-relative URLs; reject dangerous schemes before any write.
 * Path-relative means a single leading `/` NOT followed by `/` or `\`: protocol-relative
 * `//host` and backslash-authority `/\host` both resolve cross-host in browsers (WHATWG
 * slash-normalization for special schemes) and are rejected as open-redirect/phishing vectors.
 * The host should re-use this guard at render, never re-author it.
 */
export function assertAllowedMenuUrl(url: string): string {
  const trimmed = url.replace(/[\u0000-\u001F\u007F]/g, '').trim()
  if (trimmed.startsWith('/')) {
    const next = trimmed.charCodeAt(1)
    // 47 = '/', 92 = backslash: protocol-relative authority, not a path. Reject.
    if (next === 47 || next === 92) throw new MenuUrlSchemeError(url)
    return trimmed
  }
  const colon = trimmed.indexOf(':')
  if (colon === -1) {
    throw new MenuUrlSchemeError(url)
  }
  const scheme = trimmed.slice(0, colon).toLowerCase()
  if (ALLOWED_SCHEMES.has(scheme)) return trimmed
  throw new MenuUrlSchemeError(url)
}
