"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getVipValidationsById = exports.getStorageInitialValues = exports.getHostDiscoveryInitialValues = exports.isSubnetInIPv6 = exports.isDualStack = exports.canBeDualStack = exports.canSelectNetworkTypeSDN = exports.isAdvNetworkConf = exports.clusterNetworksEqual = exports.serviceNetworksEqual = exports.getSubnetFromMachineNetworkCidr = exports.getHostSubnets = exports.getHumanizedSubnet = exports.getHumanizedSubnetRange = exports.getSubnet = exports.getOpenshiftVersionText = void 0;
exports.filterValidationsInfoByGroup = filterValidationsInfoByGroup;
exports.filterValidationsInfoByStatus = filterValidationsInfoByStatus;
const ip_address_1 = require("ip-address");
const config_1 = require("../../config");
const utils_1 = require("../../utils");
const selectors_1 = require("../../selectors");
const types_1 = require("../../types");
const utils_2 = require("../hosts/utils");
const utils_3 = require("../../utils");
const getBetaVersionText = (openshiftVersion, versions) => {
    const versionSelected = versions.find((version) => version.version === openshiftVersion);
    return (versionSelected === null || versionSelected === void 0 ? void 0 : versionSelected.supportLevel) === 'beta' ? '- Developer preview release' : '';
};
const getMultiVersionText = (openshiftVersion, cpuArchitecture) => {
    if (!cpuArchitecture || openshiftVersion.includes('multi')) {
        return '';
    }
    return cpuArchitecture === types_1.CpuArchitecture.MULTI ? ' (multi)' : '';
};
const getOpenshiftVersionText = (params) => {
    return `${params.openshiftVersion} ${params.withPreviewText && params.versions
        ? getBetaVersionText(params.openshiftVersion, params.versions)
        : ''} ${params.withMultiText ? getMultiVersionText(params.openshiftVersion, params.cpuArchitecture) : ''}`;
};
exports.getOpenshiftVersionText = getOpenshiftVersionText;
const getSubnet = (cidr) => {
    if (ip_address_1.Address4.isValid(cidr)) {
        return new ip_address_1.Address4(cidr);
    }
    else if (ip_address_1.Address6.isValid(cidr)) {
        return new ip_address_1.Address6(cidr);
    }
    else {
        return null;
    }
};
exports.getSubnet = getSubnet;
const getHumanizedSubnetRange = (subnet) => {
    if (subnet) {
        const subnetStart = subnet.startAddress().correctForm();
        const subnetEnd = subnet.endAddress().correctForm();
        return `(${subnetStart} - ${subnetEnd})`;
    }
    return '';
};
exports.getHumanizedSubnetRange = getHumanizedSubnetRange;
const getHumanizedSubnet = (subnet) => {
    if (subnet) {
        return `${subnet.address} ${(0, exports.getHumanizedSubnetRange)(subnet)}`;
    }
    return '';
};
exports.getHumanizedSubnet = getHumanizedSubnet;
const buildHostnameMap = (hosts) => {
    return hosts.reduce((acc, host) => {
        const inventory = (0, utils_3.stringToJSON)(host.inventory) || {};
        acc = Object.assign(Object.assign({}, acc), { [host.id]: (0, utils_2.getHostname)(host, inventory) });
        return acc;
    }, {});
};
const getHostSubnets = (cluster, addInvalidNetworks) => {
    var _a, _b;
    const hostnameMap = buildHostnameMap(cluster.hosts || []);
    // Transform the data to handle the optional values
    const hostNetworkList = ((_a = cluster.hostNetworks) === null || _a === void 0 ? void 0 : _a.map((hn) => ({
        cidr: hn.cidr || '',
        hostIds: hn.hostIds || [],
        isValid: true,
    }))) || [];
    const hostNetworkCidrs = hostNetworkList.map((item) => item.cidr);
    if (addInvalidNetworks) {
        (_b = cluster.machineNetworks) === null || _b === void 0 ? void 0 : _b.forEach((mn) => {
            // If the machine networks are not present in the hostNetworks (the interface may have changed),
            // it must be added so that it's shown as selected and the user can select the correct one
            if (!hostNetworkCidrs.includes(mn.cidr || '')) {
                hostNetworkList.push({
                    cidr: mn.cidr || '',
                    hostIds: [],
                    isValid: false,
                });
            }
        });
    }
    return hostNetworkList.map((networkItem) => {
        return {
            subnet: networkItem.cidr,
            hostIDs: networkItem.hostIds.map((id) => hostnameMap[id] || id),
            humanized: (0, exports.getHumanizedSubnet)((0, exports.getSubnet)(networkItem.cidr)),
            isValid: networkItem.isValid,
        };
    });
};
exports.getHostSubnets = getHostSubnets;
const getSubnetFromMachineNetworkCidr = (machineNetworkCidr) => {
    if (!machineNetworkCidr) {
        return config_1.NO_SUBNET_SET;
    }
    const subnet = (0, exports.getSubnet)(machineNetworkCidr);
    return subnet === null || subnet === void 0 ? void 0 : subnet.address;
};
exports.getSubnetFromMachineNetworkCidr = getSubnetFromMachineNetworkCidr;
const serviceNetworksEqual = (array1, array2) => {
    const cidrs = array2.map((elem) => elem.cidr);
    return array1.length === array2.length && array1.every((network) => cidrs.includes(network.cidr));
};
exports.serviceNetworksEqual = serviceNetworksEqual;
const clusterNetworksEqual = (array1, array2) => array1.length === array2.length &&
    array1.every((clusterNetwork) => array2.find((network) => network.cidr === clusterNetwork.cidr && network.hostPrefix === clusterNetwork.hostPrefix));
exports.clusterNetworksEqual = clusterNetworksEqual;
const isAdvNetworkConf = (cluster, defaultNetworkValues) => !((0, exports.serviceNetworksEqual)(cluster.serviceNetworks || [], defaultNetworkValues.serviceNetworksIpv4 || []) &&
    (0, exports.clusterNetworksEqual)(cluster.clusterNetworks || [], defaultNetworkValues.clusterNetworksIpv4 || []));
exports.isAdvNetworkConf = isAdvNetworkConf;
const canSelectNetworkTypeSDN = (isSNO, isIPv6) => {
    return !(isSNO || isIPv6);
};
exports.canSelectNetworkTypeSDN = canSelectNetworkTypeSDN;
const canBeDualStack = (subnets) => subnets.some((subnet) => ip_address_1.Address4.isValid(subnet.subnet)) &&
    subnets.some((subnet) => ip_address_1.Address6.isValid(subnet.subnet));
exports.canBeDualStack = canBeDualStack;
const areNetworksDualStack = (networks, openshiftVersion) => {
    if (!networks || networks.length < 2) {
        return false;
    }
    const firstCidr = networks[0].cidr || '';
    const secondCidr = networks[1].cidr || '';
    // For OCP >= 4.12, allow either IPv4 or IPv6 as primary, with opposite as secondary
    if (openshiftVersion && (0, utils_1.isMajorMinorVersionEqualOrGreater)(openshiftVersion, '4.12')) {
        return ((ip_address_1.Address4.isValid(firstCidr) && ip_address_1.Address6.isValid(secondCidr)) ||
            (ip_address_1.Address6.isValid(firstCidr) && ip_address_1.Address4.isValid(secondCidr)));
    }
    // For older versions, require IPv4 as primary and IPv6 as secondary
    return ip_address_1.Address4.isValid(firstCidr) && ip_address_1.Address6.isValid(secondCidr);
};
const isDualStack = ({ machineNetworks, clusterNetworks, serviceNetworks, openshiftVersion, }) => areNetworksDualStack(machineNetworks, openshiftVersion) &&
    areNetworksDualStack(clusterNetworks, openshiftVersion) &&
    areNetworksDualStack(serviceNetworks, openshiftVersion);
exports.isDualStack = isDualStack;
const isSubnetInIPv6 = ({ clusterNetworkCidr, machineNetworkCidr, serviceNetworkCidr, }) => ip_address_1.Address6.isValid(clusterNetworkCidr || '') ||
    ip_address_1.Address6.isValid(machineNetworkCidr || '') ||
    ip_address_1.Address6.isValid(serviceNetworkCidr || '');
exports.isSubnetInIPv6 = isSubnetInIPv6;
const getHostDiscoveryInitialValues = (cluster) => {
    return {
        usePlatformIntegration: (0, selectors_1.isClusterPlatformTypeVM)(cluster),
        schedulableMasters: (0, selectors_1.selectSchedulableMasters)(cluster),
    };
};
exports.getHostDiscoveryInitialValues = getHostDiscoveryInitialValues;
const getStorageInitialValues = () => {
    // TODO (dchason): add initial values to node labeling
    return {
        nodeLabeling: '',
    };
};
exports.getStorageInitialValues = getStorageInitialValues;
function filterValidationsInfoByGroup(validationsInfo, selectedGroups = ['configuration', 'hosts-data', 'network', 'operators']) {
    const result = {};
    Object.keys(validationsInfo).forEach((groupKeyStr) => {
        const groupKey = groupKeyStr;
        if (selectedGroups.includes(groupKey)) {
            result[groupKey] = validationsInfo[groupKey];
        }
    });
    return result;
}
function filterValidationsInfoByStatus(validationsInfo, selectedStatuses = ['failure', 'pending', 'error']) {
    const result = {};
    Object.entries(validationsInfo).forEach(([groupKeyStr, validations = []]) => {
        const filteredValidations = validations.filter((validation) => selectedStatuses.includes(validation.status));
        if (filteredValidations.length) {
            const groupKey = groupKeyStr;
            result[groupKey] = filteredValidations;
        }
    });
    return result;
}
const getVipValidationsById = (t, validationsInfoString) => {
    const validationsInfo = (0, utils_3.stringToJSON)(validationsInfoString) || {};
    const failedDhcpAllocationMessageStubs = [
        t('ai:VIP IP allocation from DHCP server has been timed out'), // TODO(jtomasek): remove this one once it is no longer in backend
        t('ai:IP allocation from the DHCP server timed out.'),
    ];
    return (validationsInfo.network || []).reduce((lookup, validation) => {
        if (['api-vips-defined', 'ingress-vips-defined'].includes(validation.id)) {
            const vipId = validation.id;
            lookup[vipId] =
                validation.status === 'failure' &&
                    failedDhcpAllocationMessageStubs.find((stub) => validation.message.match(stub))
                    ? validation.message
                    : undefined;
        }
        return lookup;
    }, {});
};
exports.getVipValidationsById = getVipValidationsById;
//# sourceMappingURL=utils.js.map