import z from "zod";

export function isValidCIDR(cidr: string): boolean {
    return z.string().cidr().safeParse(cidr).success;
}

export function isValidIP(ip: string): boolean {
    return z.string().ip().safeParse(ip).success;
}

export function isValidUrlGlobPattern(pattern: string): boolean {
    // Remove leading slash if present
    pattern = pattern.startsWith("/") ? pattern.slice(1) : pattern;

    // Empty string is not valid
    if (!pattern) {
        return false;
    }

    // Split path into segments
    const segments = pattern.split("/");

    // Check each segment
    for (let i = 0; i < segments.length; i++) {
        const segment = segments[i];

        // Empty segments are not allowed (double slashes), except at the end
        if (!segment && i !== segments.length - 1) {
            return false;
        }

        // Check each character in the segment
        for (let j = 0; j < segment.length; j++) {
            const char = segment[j];

            // Check for percent-encoded sequences
            if (char === "%" && j + 2 < segment.length) {
                const hex1 = segment[j + 1];
                const hex2 = segment[j + 2];
                if (
                    !/^[0-9A-Fa-f]$/.test(hex1) ||
                    !/^[0-9A-Fa-f]$/.test(hex2)
                ) {
                    return false;
                }
                j += 2; // Skip the next two characters
                continue;
            }

            // Allow:
            // - unreserved (A-Z a-z 0-9 - . _ ~)
            // - sub-delims (! $ & ' ( ) * + , ; =)
            // - @ : for compatibility with some systems
            if (!/^[A-Za-z0-9\-._~!$&'()*+,;#=@:]$/.test(char)) {
                return false;
            }
        }
    }

    return true;
}

export function isUrlValid(url: string | undefined) {
    if (!url) return true; // the link is optional in the schema so if it's empty it's valid
    var pattern = new RegExp(
        "^(https?:\\/\\/)?" + // protocol
            "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name
            "((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address
            "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path
            "(\\?[;&a-z\\d%_.~+=-]*)?" + // query string
            "(\\#[-a-z\\d_]*)?$",
        "i"
    );
    return !!pattern.test(url);
}

export function isTargetValid(value: string | undefined) {
    if (!value) return true;

    const DOMAIN_REGEX =
        /^[a-zA-Z0-9_](?:[a-zA-Z0-9-_]{0,61}[a-zA-Z0-9_])?(?:\.[a-zA-Z0-9_](?:[a-zA-Z0-9-_]{0,61}[a-zA-Z0-9_])?)*$/;
    const IPV4_REGEX =
        /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
    const IPV6_REGEX = /^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$/i;

    if (IPV4_REGEX.test(value) || IPV6_REGEX.test(value)) {
        return true;
    }

    return DOMAIN_REGEX.test(value);
}
