"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.formDataFromInfraEnvField = void 0;
const tslib_1 = require("tslib");
const findLastIndex_js_1 = tslib_1.__importDefault(require("lodash-es/findLastIndex.js"));
const nmstateYaml_1 = require("./nmstateYaml");
const protocolVersion_1 = require("./protocolVersion");
const emptyData_1 = require("./emptyData");
const nmstateTypes_1 = require("./nmstateTypes");
const dummyData_1 = require("./dummyData");
const findAllRealInterfaces = (interfaces) => {
    return interfaces.filter((currentInterface) => !(0, dummyData_1.isDummyInterface)(currentInterface.name));
};
const parseYaml = (yaml) => {
    const lines = yaml.split('\n');
    const lastCommentIdx = (0, findLastIndex_js_1.default)(lines, (line) => line.startsWith(nmstateYaml_1.YAML_COMMENT_CHAR));
    const comments = lines.slice(0, lastCommentIdx + 1).map((line) => line.slice(1));
    return {
        comments: comments,
        nmstate: (0, nmstateYaml_1.yamlToNmstateObject)(yaml),
    };
};
const getVlanId = (interfaces) => {
    for (const nmstateInterface of interfaces) {
        if ((0, nmstateTypes_1.isVlanInterface)(nmstateInterface)) {
            return nmstateInterface.vlan.id;
        }
    }
    return null;
};
const getIpAddress = (networkInterface, protocolVersion) => {
    const ipAddressData = networkInterface[protocolVersion];
    if (ipAddressData === undefined) {
        return ''; //handle case 4
    }
    if (!ipAddressData.address || !ipAddressData.address.length) {
        throw `Nmstate yaml doesn't contain an address for protocol version ${protocolVersion}`;
    }
    return ipAddressData.address[0].ip;
};
const getDns = (nmstate) => {
    var _a;
    const dnsServers = (_a = nmstate['dns-resolver']) === null || _a === void 0 ? void 0 : _a.config.server;
    if (!dnsServers || !dnsServers.length) {
        throw `Nmstate YAML doesn't contain dns-resolver section`;
    }
    return dnsServers.join(',');
};
const getGateway = (nmstate, protocolVersion) => {
    var _a;
    const routesConfig = (_a = nmstate['routes']) === null || _a === void 0 ? void 0 : _a.config;
    if (!routesConfig) {
        throw `Nmstate yaml doesn't contain routes section`;
    }
    return routesConfig[(0, nmstateYaml_1.getProtocolVersionIdx)(protocolVersion)]['next-hop-address'];
};
const getNetworkWideConfigurations = (nmstate, protocolType, machineNetworks) => {
    const vlanId = getVlanId(nmstate.interfaces);
    const networkWide = (0, emptyData_1.getEmptyNetworkWideConfigurations)();
    networkWide.dns = getDns(nmstate);
    networkWide.protocolType = protocolType;
    if (vlanId) {
        networkWide.useVlan = true;
        networkWide.vlanId = vlanId;
    }
    for (const protocolVersion of (0, protocolVersion_1.getShownProtocolVersions)(protocolType)) {
        networkWide.ipConfigs[protocolVersion].gateway = getGateway(nmstate, protocolVersion);
        const [ip, prefixLength] = machineNetworks[protocolVersion].split('/');
        networkWide.ipConfigs[protocolVersion].machineNetwork = {
            ip: ip,
            prefixLength: parseInt(prefixLength),
        };
    }
    return networkWide;
};
const getFormViewHost = (infraEnvHost, protocolType) => {
    var _a, _b;
    if (!infraEnvHost.macInterfaceMap || !infraEnvHost.networkYaml) {
        throw `Static network config is missing information`;
    }
    const macAddress = infraEnvHost.macInterfaceMap[0].macAddress;
    if (!macAddress) {
        throw `Static network config is missing mac address`;
    }
    const { nmstate } = parseYaml(infraEnvHost.networkYaml);
    const realInterfaces = findAllRealInterfaces(nmstate.interfaces);
    const firstInterface = realInterfaces[0];
    const secondInterface = realInterfaces[1]; // Puede ser undefined
    let bondInterface;
    let nonBondInterface;
    if (firstInterface) {
        if (firstInterface.type === nmstateTypes_1.NmstateInterfaceType.BOND) {
            bondInterface = firstInterface;
            nonBondInterface = secondInterface;
        }
        else {
            nonBondInterface = firstInterface;
            bondInterface =
                (secondInterface === null || secondInterface === void 0 ? void 0 : secondInterface.type) === nmstateTypes_1.NmstateInterfaceType.BOND ? secondInterface : undefined;
        }
    }
    if (realInterfaces.length === 0) {
        //handle case 2
        return null;
    }
    //handle cases 3 and 4
    const ret = {
        macAddress,
        ips: {
            ipv4: '',
            ipv6: '',
        },
        bondType: 'active-backup',
        bondPrimaryInterface: '',
        bondSecondaryInterface: '',
        useBond: false,
    };
    if ((bondInterface === null || bondInterface === void 0 ? void 0 : bondInterface.type) === nmstateTypes_1.NmstateInterfaceType.BOND) {
        ret.useBond = true;
        ret.bondType = bondInterface['link-aggregation'].mode;
        ret.bondPrimaryInterface = (_a = infraEnvHost.macInterfaceMap[0].macAddress) !== null && _a !== void 0 ? _a : '';
        ret.bondSecondaryInterface = (_b = infraEnvHost.macInterfaceMap[1].macAddress) !== null && _b !== void 0 ? _b : '';
    }
    for (const protocolVersion of (0, protocolVersion_1.getShownProtocolVersions)(protocolType)) {
        const interfaceToUse = nonBondInterface || bondInterface;
        if (interfaceToUse) {
            ret.ips[protocolVersion] = getIpAddress(interfaceToUse, protocolVersion);
        }
    }
    return ret;
};
const formDataFromInfraEnvField = (staticHostConfigs) => {
    if (!staticHostConfigs.length) {
        throw `Static network config is empty`;
    }
    const firstHostConfig = staticHostConfigs[0];
    if (!firstHostConfig.macInterfaceMap || !firstHostConfig.networkYaml) {
        throw 'Static network config first host is missing fields';
    }
    const { comments, nmstate } = parseYaml(firstHostConfig.networkYaml);
    const protocolType = (0, nmstateYaml_1.getProtocolType)(comments);
    if (!protocolType) {
        //handle case 1
        return {
            networkWide: (0, emptyData_1.getEmptyNetworkWideConfigurations)(),
            hosts: [],
        };
    }
    const machineNetworks = (0, nmstateYaml_1.getMachineNetworks)(comments);
    const networkWide = getNetworkWideConfigurations(nmstate, protocolType, machineNetworks);
    //handles cases 2 - 4
    const hosts = [];
    for (const hostConfig of staticHostConfigs) {
        const formViewHost = getFormViewHost(hostConfig, protocolType);
        if (formViewHost) {
            //in case 2 - formViewHost will be null and won't be added to hosts
            //in case 3 - formViewHost will contain all required data
            //in case 4 - host will contain ipv4 address and user will need to configure ipv6. the static ip wizard step will be recognized as incomplete
            hosts.push(formViewHost);
        }
    }
    return {
        networkWide: networkWide,
        hosts: hosts,
    };
};
exports.formDataFromInfraEnvField = formDataFromInfraEnvField;
//# sourceMappingURL=formDataFromInfraEnvField.js.map