<?php
declare(strict_types=1);

namespace Ekesto\CacheInvalidator\Integrations\Caching;

/**
 * Shared URL normalization for cache adapter signal payloads.
 */
final class CacheAdapterUrlNormalizer
{
    /**
     * Normalize a URL candidate into one validated absolute URL.
     *
     * @param mixed $candidate URL candidate.
     * @return string
     */
    public static function normalize($candidate): string
    {
        if (!is_scalar($candidate)) {
            return '';
        }

        $url = trim((string) $candidate);
        if ($url === '') {
            return '';
        }

        $url = esc_url_raw($url);
        if ($url === '') {
            return '';
        }

        $parts = wp_parse_url($url);
        if (!is_array($parts)) {
            return '';
        }

        $scheme = isset($parts['scheme']) ? strtolower((string) $parts['scheme']) : '';
        $host = isset($parts['host']) ? strtolower(trim((string) $parts['host'])) : '';
        if (($scheme !== 'http' && $scheme !== 'https') || $host === '') {
            return '';
        }

        $homeParts = wp_parse_url((string) home_url('/'));
        if (!is_array($homeParts)) {
            return '';
        }

        $homeHost = isset($homeParts['host']) ? strtolower(trim((string) $homeParts['host'])) : '';
        if ($homeHost === '') {
            return '';
        }

        // NOTE:
        // Same-origin validation is intentionally implemented locally.
        // wp_http_validate_url() is NOT used because it performs a strict host
        // comparison that does not normalize 'www.' or trailing dots, causing
        // false negatives for valid same-origin URLs in dev environments.
        $normalizeHost = static function (string $host): string {
            $host = strtolower(trim($host));
            $host = rtrim($host, '.');
            if (strpos($host, 'www.') === 0) {
                $host = substr($host, 4);
            }
            return $host;
        };

        if ($normalizeHost($host) !== $normalizeHost($homeHost)) {
            return '';
        }

        $homeScheme = isset($homeParts['scheme']) ? strtolower((string) $homeParts['scheme']) : '';
        if ($homeScheme === 'http' || $homeScheme === 'https') {
            $scheme = $homeScheme;
        }

        $path = isset($parts['path']) ? (string) $parts['path'] : '/';
        if ($path === '') {
            $path = '/';
        } elseif ($path !== '/') {
            $path = rtrim($path, '/');
        }

        $query = isset($parts['query']) && (string) $parts['query'] !== ''
            ? '?' . (string) $parts['query']
            : '';
        $port = isset($parts['port']) ? ':' . (int) $parts['port'] : '';
        $canonical = $scheme . '://' . $host . $port . $path . $query;
        $canonical = esc_url_raw($canonical);
        if ($canonical === '') {
            return '';
        }

        return $canonical;
    }
}
