/**
 * Classe permettant de construire une URL pour l'interrogation d'une API externe
 */
class UrlUtils {
  /**
   * Concatenate a base url and a tail
   * @param base
   * @param tails
   * @private
   */
  public static join (base: string|number, ...tails: Array<string|number>): string {
    let url = String(base)
    tails.forEach((tail: string|number) => {
      url = url.replace(/^|\/$/g, '') + '/' + String(tail).replace(/^\/?|$/g, '')
    })
    return url
  }

  /**
   * Prepend the 'https://' part if neither 'http://' nor 'https://' prefixes are present, else does nothing
   *
   * @param url
   */
  public static prependHttps (url: string): string {
    if (!url.match(/^https?:\/\/.*/)) {
      url = 'https://' + url;
    }
    return url;
  }

  /**
   * Parse an URI to retrieve a parameter
   *
   * @param uri
   * @param parameter
   * @param default_
   * @private
   */
  public static getParameter (
      uri: string,
      parameter: string,
      default_: string | number | null = null
  ): string | number | null {
    uri = UrlUtils.prependHttps(uri)

    const urlParams = new URL(uri).searchParams;
    let value: string | number | null = urlParams.get(parameter);

    if (value && (default_ === null || Number.isInteger(default_)) && /^\d+$/.test(value)) {
      // On convertit automatiquement si et seulement la valeur par défaut est elle-même un entier ou n'est pas définie
      value = parseInt(value)
    }

    return value ?? default_
  }

  /**
   * Extrait l'ID de l'URI passée en paramètre
   * L'URI est supposée être de la forme `.../foo/bar/{id}`,
   * où l'id est un identifiant numérique, à moins que isLiteral soit défini comme vrai.
   * Dans ce cas, si isLiteral est vrai, l'id sera retourné sous forme de texte.
   *
   *
   * @param uri
   * @param isLiteral
   */
  public static extractIdFromUri (uri: string, isLiteral: boolean = false): number|string|null {
    const partUri: Array<string> = uri.split('/')
    const id: string = partUri.pop() ?? ''

    if (!id || (!isLiteral && isNaN(id as any))) {
      throw new Error('no id found')
    }
    return isLiteral ? id : parseInt(id)
  }

  /**
   * Découpe une URI au niveau des '/'
   * Utilisé entre autres pour le breadcrumb
   *
   * Ex:
   *
   *    foo/bar/1   =>  ['foo', 'bar', '1']
   *    /foo/bar/1   =>  ['foo', 'bar', '1']
   *    https://domain.com/foo/bar/1   =>  ['https:', 'domain.com', 'foo', 'bar', '1']
   *
   *
   * @param uri
   */
  public static split(uri: string) {
    return uri.split('/').filter((s) => s.length > 0)
  }
}

export default UrlUtils
