<?php
declare(strict_types=1);

namespace App\Service\Utils;

/**
 * Building url utilities
 */
class UrlBuilder
{
    /**
     * Concatenate a base url and a path
     *
     * @param string $url The base url
     * @param string $path The following path
     * @return string
     */
    public static function concatPath(string $url, string $path): string
    {
        return rtrim($url, '/') . '/' . ltrim($path, '/');
    }

    /**
     * Concatenate an url and a list of parameters
     *
     * @param string $url
     * @param list<string | int> $parameters
     * @return string
     */
    public static function concatParameters(string $url, array $parameters = []): string
    {
        if (!$parameters) { return $url; }
        $url = rtrim($url, '?&/');
        $query = implode(
            '&',
            array_map(
                static function ($k, $v = '') {
                    $q = urlencode((string)$k);
                    if ((string)$v) {
                        $q .= '=' . urlencode((string)$v);
                    }
                    return $q;
                },
                array_keys($parameters),
                array_values($parameters)
            )
        );
        return $url . (str_contains($url, '?') ?  '&' : '?') . $query;
    }

    /**
     * Prepend the 'https://' part if neither 'http://' of 'https://' is present, else: does nothing
     *
     * @param string $url
     * @return string
     */
    public static function prependHttps(string $url): string
    {
        if (!preg_match('/^https?:\/\/.*/', $url)) {
            $url = 'https://' . $url;
        }
        return $url;
    }

    /**
     * Build an url
     *
     * @param string $url The base url
     * @param string $path A path to append (can be an empty string)
     * @param list<string> $parameters A list of parameters (can be an empty array)
     * @param bool $preprendHttps Should the 'https://' be prepended if missing
     * @return string
     */
    public static function concat(string $url, string $path, array $parameters, bool $preprendHttps = false): string
    {
        $url = self::concatParameters(self::concatPath($url, $path), $parameters);
        if ($preprendHttps) {
            $url = self::prependHttps($url);
        }
        return $url;
    }
}
