/**
 * Normalizes a given URL by performing the following operations:
 *
 * 1. Ensures that the URL has a protocol by defaulting to 'wss://' if no protocol is provided.
 * 2. Creates a `URL` object to easily manipulate and normalize the URL components.
 * 3. Normalizes the pathname by:
 *    - Replacing multiple consecutive slashes with a single slash.
 *    - Removing the trailing slash if it exists.
 * 4. Removes the port number if it is the default port for the protocol:
 *    - Port `80` for 'ws:' (WebSocket) protocol.
 *    - Port `443` for 'wss:' (WebSocket Secure) protocol.
 * 5. Sorts the query parameters alphabetically.
 * 6. Clears any fragment (hash) identifier from the URL.
 *
 * @param urlString - The URL string to be normalized.
 * @returns A normalized URL string.
 */
export function normalizeWebSocketURL(urlString: string): string {
  // If the URL string does not contain a protocol (e.g., "http://", "https://"),
  // prepend "wss://" (WebSocket Secure) by default.
  if (urlString.indexOf('://') === -1) urlString = 'wss://' + urlString

  // Create a URL object from the provided URL string.
  const url = new URL(urlString)

  // Normalize the pathname by replacing multiple consecutive slashes with a single slash.
  url.pathname = url.pathname.replace(/\/+/g, '/')

  // Remove the trailing slash from the pathname if it exists.
  if (url.pathname.endsWith('/')) url.pathname = url.pathname.slice(0, -1)

  // Remove the port number if it is 80 for "ws:" protocol or 443 for "wss:" protocol, as these are default ports.
  if (
    (url.port === '80' && url.protocol === 'ws:') ||
    (url.port === '443' && url.protocol === 'wss:')
  )
    url.port = ''

  // Sort the search parameters alphabetically.
  url.searchParams.sort()

  // Clear any hash fragment from the URL.
  url.hash = ''

  // Return the normalized URL as a string.
  return url.toString()
}
