"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const yaml = tslib_1.__importStar(require("js-yaml"));
const react_core_1 = require("@patternfly/react-core");
const formik_1 = require("formik");
const Yup = tslib_1.__importStar(require("yup"));
const common_1 = require("../../../common");
const react_code_editor_1 = require("@patternfly/react-code-editor");
const minus_circle_icon_1 = require("@patternfly/react-icons/dist/js/icons/minus-circle-icon");
const plus_circle_icon_1 = require("@patternfly/react-icons/dist/js/icons/plus-circle-icon");
const common_2 = require("../common");
const utils_1 = require("../../../common/utils");
const use_translation_wrapper_1 = require("../../../common/hooks/use-translation-wrapper");
const getFieldError = (errors, fieldName) => {
    var _a;
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
    return ((_a = errors[fieldName]) === null || _a === void 0 ? void 0 : _a[0]) || '';
};
const MacMapping = () => {
    const [field] = (0, formik_1.useField)({
        name: 'macMapping',
    });
    const { errors } = (0, formik_1.useFormikContext)();
    const fieldId = (0, common_1.getFieldId)('macMapping', 'input');
    const { t } = (0, use_translation_wrapper_1.useTranslation)();
    return (React.createElement(react_core_1.FormGroup, { fieldId: fieldId, label: t('ai:MAC to interface name mapping') },
        React.createElement(formik_1.FieldArray, { name: "macMapping", render: ({ push, remove }) => (React.createElement(react_core_1.Grid, { hasGutter: true },
                React.createElement(react_core_1.GridItem, { span: 5 },
                    React.createElement(react_core_1.Content, { component: react_core_1.ContentVariants.small }, "MAC address")),
                React.createElement(react_core_1.GridItem, { span: 5 },
                    React.createElement(react_core_1.Content, { component: react_core_1.ContentVariants.small }, "NIC")),
                field.value.map((mac, index) => {
                    const macField = `macMapping[${index}].macAddress`;
                    const nameField = `macMapping[${index}].name`;
                    return (React.createElement(React.Fragment, { key: index },
                        React.createElement(react_core_1.GridItem, { span: 5 },
                            React.createElement(common_1.InputField, { name: macField, inputError: getFieldError(errors, macField) })),
                        React.createElement(react_core_1.GridItem, { span: 5 },
                            React.createElement(common_1.InputField, { name: nameField, inputError: getFieldError(errors, nameField) })),
                        index !== 0 && (React.createElement(react_core_1.GridItem, { span: 2 },
                            React.createElement(minus_circle_icon_1.MinusCircleIcon, { onClick: () => remove(index) })))));
                }),
                React.createElement(react_core_1.GridItem, { span: 6 },
                    React.createElement(react_core_1.Button, { icon: React.createElement(plus_circle_icon_1.PlusCircleIcon, null), onClick: () => push({ macAddress: '', name: '' }), variant: "link", isInline: true }, t('ai:Add more'))))) })));
};
const getNMState = (values, infraEnv) => {
    var _a, _b, _c;
    const config = yaml.load(values.nmState);
    const nmState = {
        apiVersion: 'agent-install.openshift.io/v1beta1',
        kind: 'NMStateConfig',
        metadata: {
            generateName: `${((_a = infraEnv.metadata) === null || _a === void 0 ? void 0 : _a.name) || ''}-`,
            namespace: (_b = infraEnv.metadata) === null || _b === void 0 ? void 0 : _b.namespace,
            labels: {
                [common_2.AGENT_BMH_NAME_LABEL_KEY]: values.name,
                [common_2.INFRAENV_AGENTINSTALL_LABEL_KEY]: ((_c = infraEnv === null || infraEnv === void 0 ? void 0 : infraEnv.metadata) === null || _c === void 0 ? void 0 : _c.name) || '',
            },
        },
        spec: {
            // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
            config,
            interfaces: values.macMapping.filter((m) => m.macAddress.length && m.name.length),
        },
    };
    return nmState;
};
const getValidationSchema = (usedHostnames, origHostname, t) => {
    return Yup.object({
        name: Yup.string().required(t('ai:Required field')),
        hostname: (0, common_1.richNameValidationSchema)(t, usedHostnames, origHostname),
        bmcAddress: (0, common_1.bmcAddressValidationSchema)(t),
        username: Yup.string().required(t('ai:Required field')),
        password: Yup.string().required(t('ai:Required field')),
        bootMACAddress: (0, common_1.macAddressValidationSchema)(t),
        nmState: Yup.string(),
        macMapping: Yup.array().of(Yup.object().shape({
            macAddress: (0, common_1.macAddressValidationSchema)(t).when('name', {
                is: (name) => !!name,
                then: (schema) => schema.required(t('ai:MAC has to be specified')),
            }),
            name: Yup.string().when('macAddress', {
                is: (name) => !!name,
                then: () => Yup.string().required(t('ai:Name has to be specified')),
            }),
        }, [['name', 'macAddress']])),
    });
};
const emptyValues = {
    name: '',
    hostname: '',
    bmcAddress: '',
    username: '',
    password: '',
    bootMACAddress: '',
    disableCertificateVerification: true, // TODO(mlibra)
    online: true,
    nmState: `interfaces:
  - name: <nic1_name>
    type: ethernet
    state: up
    ipv4:
      address:
      - ip: <ip_address>
        prefix-length: 24
      enabled: true
dns-resolver:
  config:
    server:
    - <dns_ip_address>
routes:
  config:
  - destination: 0.0.0.0/0
    next-hop-address: <next_hop_ip_address>
    next-hop-interface: <next_hop_nic1_name>
  `,
    macMapping: [{ macAddress: '', name: '' }],
};
const getInitValues = (bmh, nmState, secret, isEdit, addNMState) => {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
    let values = emptyValues;
    if (isEdit) {
        values = {
            name: ((_a = bmh === null || bmh === void 0 ? void 0 : bmh.metadata) === null || _a === void 0 ? void 0 : _a.name) || '',
            hostname: ((_c = (_b = bmh === null || bmh === void 0 ? void 0 : bmh.metadata) === null || _b === void 0 ? void 0 : _b.annotations) === null || _c === void 0 ? void 0 : _c[common_2.BMH_HOSTNAME_ANNOTATION]) || '',
            bmcAddress: ((_e = (_d = bmh === null || bmh === void 0 ? void 0 : bmh.spec) === null || _d === void 0 ? void 0 : _d.bmc) === null || _e === void 0 ? void 0 : _e.address) || '',
            username: ((_f = secret === null || secret === void 0 ? void 0 : secret.data) === null || _f === void 0 ? void 0 : _f.username) ? atob(secret.data.username) : '',
            password: ((_g = secret === null || secret === void 0 ? void 0 : secret.data) === null || _g === void 0 ? void 0 : _g.password) ? atob(secret.data.password) : '',
            bootMACAddress: ((_h = bmh === null || bmh === void 0 ? void 0 : bmh.spec) === null || _h === void 0 ? void 0 : _h.bootMACAddress) || '',
            disableCertificateVerification: !!((_k = (_j = bmh === null || bmh === void 0 ? void 0 : bmh.spec) === null || _j === void 0 ? void 0 : _j.bmc) === null || _k === void 0 ? void 0 : _k.disableCertificateVerification),
            online: !!((_l = bmh === null || bmh === void 0 ? void 0 : bmh.spec) === null || _l === void 0 ? void 0 : _l.online),
            nmState: nmState ? yaml.dump((_m = nmState === null || nmState === void 0 ? void 0 : nmState.spec) === null || _m === void 0 ? void 0 : _m.config) : emptyValues.nmState,
            macMapping: ((_o = nmState === null || nmState === void 0 ? void 0 : nmState.spec) === null || _o === void 0 ? void 0 : _o.interfaces) || [{ macAddress: '', name: '' }],
        };
    }
    if (!addNMState) {
        values.nmState = '';
    }
    return values;
};
const BMCForm = ({ onCreateBMH, onClose, hasDHCP, infraEnv, bmh, nmState, secret, isEdit, usedHostnames, }) => {
    var _a;
    const [error, setError] = React.useState();
    const handleSubmit = (values) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
        try {
            setError(undefined);
            const nmState = values.nmState ? getNMState(values, infraEnv) : undefined;
            yield onCreateBMH(values, nmState);
            onClose();
        }
        catch (e) {
            setError((0, utils_1.getErrorMessage)(e));
        }
    });
    const { t } = (0, use_translation_wrapper_1.useTranslation)();
    const { initValues, validationSchema } = React.useMemo(() => {
        var _a, _b;
        const addNmState = ((_a = infraEnv.metadata) === null || _a === void 0 ? void 0 : _a.labels) && ((_b = infraEnv.metadata) === null || _b === void 0 ? void 0 : _b.labels['networkType']) === 'static';
        const initValues = getInitValues(bmh, nmState, secret, isEdit, addNmState);
        const validationSchema = getValidationSchema(usedHostnames, initValues.hostname, t);
        return { initValues, validationSchema };
    }, [(_a = infraEnv.metadata) === null || _a === void 0 ? void 0 : _a.labels, usedHostnames, bmh, nmState, secret, isEdit, t]);
    return (React.createElement(formik_1.Formik, { initialValues: initValues, isInitialValid: false, validate: (0, common_1.getRichTextValidation)(validationSchema), onSubmit: handleSubmit }, ({ isSubmitting, isValid, submitForm }) => (React.createElement(React.Fragment, null,
        React.createElement(react_core_1.ModalBody, null,
            React.createElement(react_core_1.Form, { id: "add-bmc-form" },
                React.createElement(common_1.InputField, { label: t('ai:Name'), name: "name", placeholder: t('ai:Enter the name for the Host'), isRequired: true, isDisabled: isEdit }),
                React.createElement(common_1.RichInputField, { label: t('ai:Hostname'), name: "hostname", placeholder: t('ai:Enter the hostname for the Host'), richValidationMessages: (0, common_1.BMCValidationMessages)(t), isRequired: true }),
                React.createElement(common_1.InputField, { label: t('ai:Baseboard Management Controller Address'), name: "bmcAddress", placeholder: t('ai:Enter an address'), isRequired: true }),
                React.createElement(common_1.InputField, { label: t('ai:Boot NIC MAC Address'), name: "bootMACAddress", placeholder: t('ai:Enter an address'), helperText: t("ai:The MAC address of the host's network connected NIC that will be used to provision the host."), isRequired: true }),
                React.createElement(common_1.InputField, { label: t('ai:Username'), name: "username", placeholder: t('ai:Enter a username for the BMC'), isRequired: true }),
                React.createElement(common_1.InputField, { type: react_core_1.TextInputTypes.password, label: t('ai:Password'), name: "password", placeholder: t('ai:Enter a password for the BMC'), isRequired: true }),
                !hasDHCP && (React.createElement(React.Fragment, null,
                    React.createElement(common_1.CodeField, { label: t('ai:NMState'), name: "nmState", language: react_code_editor_1.Language.yaml, helperText: t('ai:Upload a YAML file in NMstate format (not the entire NMstate config CR) that includes your network configuration (static IPs, bonds, etc.).') }),
                    React.createElement(MacMapping, null)))),
            error && (React.createElement(react_core_1.Alert, { title: t('ai:Failed to add host'), variant: react_core_1.AlertVariant.danger, isInline: true, actionClose: React.createElement(react_core_1.AlertActionCloseButton, { onClose: () => setError(undefined) }) }, error))),
        React.createElement(react_core_1.ModalFooter, null,
            React.createElement(react_core_1.Button, { onClick: submitForm, isDisabled: isSubmitting || !isValid }, isEdit ? t('ai:Submit') : t('ai:Create')),
            React.createElement(react_core_1.Button, { onClick: onClose, variant: react_core_1.ButtonVariant.secondary }, t('ai:Cancel')))))));
};
exports.default = BMCForm;
//# sourceMappingURL=BMCForm.js.map