<?php

namespace App\Rules;

use App\Models\Environments\Environment;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

/**
 * El dominio de un entorno es una URL completa con `https://` (PRODSECU-185).
 *
 * **Por qué.** Se dieron de alta entornos con `http://`, o sin esquema, y dieron problemas
 * con la licencia. El formulario no lo impedía, y además el ejemplo que enseñaba era
 * `www.tresipunt.com`, sin esquema: invitaba a escribirlo mal.
 *
 * **Los `local` quedan fuera**, igual que en {@see UniqueEnvironmentDomain}: son los Moodles
 * de desarrollo de cada uno (`http://moodle.test`) y van por `http://` porque no tienen
 * certificado. Exigírselo dejaría sin poder darlos de alta. Si se omite `$env`, se exige,
 * que es lo seguro por defecto.
 */
class DominioConHttps implements ValidationRule
{
    public function __construct(private ?string $env = null) {}

    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $valor = trim((string) $value);

        // `parse_url` y no `str_starts_with`: «https://» a secas, o «https:// campus», empiezan
        // bien y no son una URL.
        $partes = parse_url($valor);
        $esquema = strtolower($partes['scheme'] ?? '');
        $host = $partes['host'] ?? '';
        $esUrl = $host !== '' && ! preg_match('/\s/', $valor);

        // **A los `local` solo se les perdona el `http://`, no que no sean una URL.** Antes
        // se les dejaba pasar cualquier cosa, y el dominio se pinta como enlace en media
        // docena de pantallas: un `javascript:alert(…)` guardado como dominio de un local
        // era un script que se ejecutaba al pulsarlo (auditoría de PRODSECU-215).
        if ($this->env === Environment::USO_EXENTO_DEL_INDICE) {
            if ($esUrl && in_array($esquema, ['http', 'https'], true)) {
                return;
            }

            $fail('El dominio tiene que ser una URL completa con http:// o https://, por ejemplo http://moodle.test.');

            return;
        }

        if ($esquema === 'https' && $esUrl) {
            return;
        }

        $fail($esquema === 'http'
            ? 'El dominio tiene que ir con https://, no con http://. Solo los entornos «local» pueden ir por http://.'
            : 'El dominio tiene que ser la URL completa con https:// delante, por ejemplo https://campus.cliente.com.');
    }
}
