/**
 * validators.js - 通用前端校验函数
 * 统一提供整数、端口、IPv4、掩码、MAC 等校验，避免各页面重复实现。
 *
 * 所有函数挂在全局作用域，供旧代码直接使用：
 * - isInteger(value)
 * - isValidPort(port, min, max)
 * - isValidIP(ip)
 * - isValidNetmask(mask)
 * - isValidMac(mac)
 * - getSrtPassphraseByteLength(uri)
 * - isValidSrtPassphrase(uri)
 */
(function (global) {
    'use strict';

    /**
     * 判断是否为整数（字符串或数字）
     * @param {string|number} value
     * @returns {boolean}
     */
    function isInteger(value) {
        if (typeof value === 'number') {
            return Number.isInteger(value);
        }
        if (typeof value === 'string') {
            var trimmed = value.trim();
            if (trimmed === '') return false;
            // 允许可选负号 + 纯数字
            if (!/^-?\d+$/.test(trimmed)) return false;
            var num = Number(trimmed);
            return Number.isInteger(num);
        }
        return false;
    }

    /**
     * 校验端口号是否在指定范围内
     * @param {string|number} port
     * @param {number} [min=1]
     * @param {number} [max=65535] 注意：保持与原有默认值一致
     * @returns {boolean}
     */
    function isValidPort(port, min, max) {
        min = (typeof min === 'number') ? min : 1;
        max = (typeof max === 'number') ? max : 65535;

        var num;
        if (typeof port === 'number') {
            num = port;
        } else if (typeof port === 'string' && port.trim() !== '') {
            num = Number(port.trim());
        } else {
            return false;
        }

        if (!Number.isInteger(num)) return false;
        return num >= min && num <= max;
    }

    /**
     * 校验 IPv4 地址是否合法
     * 使用与各页面 checkIp 相同的规则：每段 0-255
     * @param {string} ip
     * @returns {boolean}
     */
    function isValidIP(ip) {
        if (typeof ip !== 'string') return false;
        var trimmed = ip.trim();
        if (trimmed === '') return false;
        var pattern = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/;
        return pattern.test(trimmed);
    }

    /**
     * 校验 IPv4 子网掩码是否合法
     * 使用 NetworkSet/WifiSet 中已有的正则
     * @param {string} mask
     * @returns {boolean}
     */
    function isValidNetmask(mask) {
        if (typeof mask !== 'string') return false;
        var trimmed = mask.trim();
        if (trimmed === '') return false;
        var pattern = /^((254|252|248|240|224|192|128|0)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0))$/;
        return pattern.test(trimmed);
    }

    /**
     * 校验 MAC 地址是否合法（00:11:22:33:44:55）
     * @param {string} mac
     * @returns {boolean}
     */
    function isValidMac(mac) {
        if (typeof mac !== 'string') return false;
        var trimmed = mac.trim();
        if (trimmed === '') return false;
        var pattern = /^[a-fA-F\d]{2}(:[a-fA-F\d]{2}){5}$/;
        return pattern.test(trimmed);
    }

    /**
     * 校验 IPv6 地址是否合法（与后端 web_manager.cpp 的 ip6_stand / ip6_compress 正则一致）
     * 标准全写形式 或 :: 压缩形式
     * @param {string} addr
     * @returns {boolean}
     */
    function isValidIPv6(addr) {
        if (typeof addr !== 'string') return false;
        var trimmed = addr.trim();
        if (trimmed === '') return false;
        var ip6_stand = /^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}$/;
        var ip6_compress = /^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,5})?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,5})?)$/;
        return ip6_stand.test(trimmed) || ip6_compress.test(trimmed);
    }

    /**
     * 校验 IPv6 子网前缀长度是否合法（与后端一致：1-128）
     * @param {string|number} len
     * @returns {boolean}
     */
    function isValidIPv6Prefix(len) {
        var num;
        if (typeof len === 'number') {
            num = len;
        } else if (typeof len === 'string' && len.trim() !== '') {
            num = Number(len.trim());
        } else {
            return false;
        }
        if (!Number.isInteger(num)) return false;
        return num >= 1 && num <= 128;
    }

    /**
     * 返回 SRT URI 中最终生效的 passphrase 解码后的字节数。
     * 与后端保持一致：先按 & 分隔参数，裸 + 视为空格，%HH 只解码一次；
     * 未配置或空密码返回 0，编码 NUL 或无效输入返回 -1。
     * @param {string} uri
     * @returns {number}
     */
    function getSrtPassphraseByteLength(uri) {
        if (typeof uri !== 'string') return -1;

        var queryPos = uri.indexOf('?');
        if (queryPos < 0) return 0;

        var passphrase = null;
        var fields = uri.substring(queryPos + 1).split('&');
        for (var i = 0; i < fields.length; i++) {
            if (fields[i] === '') continue;
            var equalPos = fields[i].indexOf('=');
            var key = equalPos < 0 ? fields[i] : fields[i].substring(0, equalPos);
            key = key.replace(/^[ \t\r\n]+|[ \t\r\n]+$/g, '');
            if (key !== 'passphrase') continue;

            passphrase = equalPos < 0 ? '' : fields[i].substring(equalPos + 1);
            passphrase = passphrase.replace(/^[ \t\r\n]+|[ \t\r\n]+$/g, '');
        }

        if (passphrase === null || passphrase === '') return 0;

        var byteLength = 0;
        for (var j = 0; j < passphrase.length; j++) {
            var ch = passphrase.charAt(j);
            if (ch === '+') {
                byteLength++;
                continue;
            }

            if (ch === '%' && j + 2 < passphrase.length &&
                /^[0-9A-Fa-f]{2}$/.test(passphrase.substring(j + 1, j + 3))) {
                if (parseInt(passphrase.substring(j + 1, j + 3), 16) === 0) return -1;
                byteLength++;
                j += 2;
                continue;
            }

            var code = passphrase.charCodeAt(j);
            if (code <= 0x7f) {
                byteLength++;
            } else if (code <= 0x7ff) {
                byteLength += 2;
            } else if (code >= 0xd800 && code <= 0xdbff &&
                       j + 1 < passphrase.length) {
                var next = passphrase.charCodeAt(j + 1);
                if (next >= 0xdc00 && next <= 0xdfff) {
                    byteLength += 4;
                    j++;
                } else {
                    byteLength += 3;
                }
            } else {
                byteLength += 3;
            }
        }

        return byteLength;
    }

    function isValidSrtPassphrase(uri) {
        var byteLength = getSrtPassphraseByteLength(uri);
        return byteLength === 0 || (byteLength >= 10 && byteLength <= 79);
    }

    // 导出主函数
    global.isInteger = isInteger;
    global.isValidPort = isValidPort;
    global.isValidIP = isValidIP;
    global.isValidNetmask = isValidNetmask;
    global.isValidMac = isValidMac;
    global.isValidIPv6 = isValidIPv6;
    global.isValidIPv6Prefix = isValidIPv6Prefix;
    global.getSrtPassphraseByteLength = getSrtPassphraseByteLength;
    global.isValidSrtPassphrase = isValidSrtPassphrase;

})(window);
