<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\src\Mcp\OAuth;

/**
 * Validates a client's registered redirect URIs (RFC 7591 / OAuth 2.1 security BCP): only absolute
 * https URLs, or http on a loopback host (localhost / 127.0.0.1 / [::1]) for native/dev connectors.
 * Fragments are forbidden. This is the allow-list the whole flow keys off, so it is deliberately
 * strict — an open redirect here would let an attacker capture authorization codes.
 */
final class RedirectUriValidator
{
    private const LOOPBACK_HOSTS = ['localhost', '127.0.0.1', '::1'];

    public static function isValid(string $uri): bool
    {
        if ($uri === '') {
            return false;
        }
        $parts = parse_url($uri);
        if ($parts === false || !isset($parts['scheme'], $parts['host'])) {
            return false;
        }
        if (isset($parts['fragment'])) {
            return false;
        }

        $scheme = strtolower($parts['scheme']);
        $host   = strtolower(trim($parts['host'], '[]'));

        if ($scheme === 'https') {
            return true;
        }
        if ($scheme === 'http') {
            return \in_array($host, self::LOOPBACK_HOSTS, true);
        }

        return false;
    }

    /**
     * @param mixed $uris
     *
     * @return list<string> the cleaned, validated list — empty if any entry is invalid or none given
     */
    public static function clean(mixed $uris): array
    {
        if (!\is_array($uris) || $uris === []) {
            return [];
        }
        $out = [];
        foreach ($uris as $uri) {
            if (!\is_string($uri) || !self::isValid($uri)) {
                return [];
            }
            $out[] = $uri;
        }

        return $out;
    }
}
