export const SITEMAP_PRESENCE_EVENT = "ekesto-cache-warmup:sitemap-presence";

export const parseSitemapUrls = (rawValue) => {
    if (typeof rawValue !== "string" || rawValue.trim() === "") {
        return [];
    }

    return rawValue
        .split(/\r?\n/)
        .map((line) => line.trim())
        .filter(Boolean);
};

export const isPrivateIPv4 = (hostname) => {
    const octets = hostname.split(".");
    if (octets.length !== 4) {
        return false;
    }

    const numbers = octets.map((part) => Number(part));
    if (
        numbers.some((part, index) => (
            part < 0
            || part > 255
            || !Number.isInteger(part)
            || String(part) !== octets[index]
        ))
    ) {
        return false;
    }

    return (
        numbers[0] === 10
        || numbers[0] === 127
        || (numbers[0] === 172 && numbers[1] >= 16 && numbers[1] <= 31)
        || (numbers[0] === 192 && numbers[1] === 168)
    );
};

export const isValidSitemapHostname = (hostname) => {
    const normalized = hostname.toLowerCase().trim();

    if (normalized === "" || normalized.endsWith(".")) {
        return false;
    }

    if (
        normalized === "localhost"
        || normalized.endsWith(".localhost")
        || normalized.endsWith(".local")
        || normalized === "[::1]"
        || isPrivateIPv4(normalized)
    ) {
        return true;
    }

    const labels = normalized.split(".");
    if (labels.length < 2) {
        return false;
    }

    const validLabels = labels.every((label) => (
        /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(label)
    ));
    const tld = labels[labels.length - 1];

    return validLabels && /^[a-z]{2,}$/.test(tld);
};

export const hasInvalidSitemapUrl = (rawValue) => (
    parseSitemapUrls(rawValue).some((url) => {
        try {
            const parsed = new URL(url);
            const protocol = parsed.protocol.toLowerCase();

            return (
                (protocol !== "http:" && protocol !== "https:")
                || !isValidSitemapHostname(parsed.hostname)
            );
        } catch {
            return true;
        }
    })
);
