"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const react_1 = require("react");
const common_1 = require("../../common");
const useInfraEnvHosts_1 = tslib_1.__importDefault(require("./useInfraEnvHosts"));
const HostsService_1 = tslib_1.__importDefault(require("../services/HostsService"));
const utils_1 = require("../../common/utils");
const use_feature_1 = require("./use-feature");
const MAX_BIND_RETRY_ATTEMPTS = 3;
const useLateBinding = (cluster) => {
    const [isBinding, setIsBinding] = (0, react_1.useState)(false);
    const { addAlert, removeAlert, alerts } = (0, common_1.useAlerts)();
    const isSingleClusterFeatureEnabled = (0, use_feature_1.useFeature)('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
    const bindFailureCounts = (0, react_1.useRef)(new Map());
    const alertsRef = (0, react_1.useRef)(alerts);
    alertsRef.current = alerts;
    const { hosts: infraEnvHosts, error: infraEnvError, isLoading: infraEnvLoading, } = (0, useInfraEnvHosts_1.default)(isSingleClusterFeatureEnabled ? cluster.id : '', cluster.cpuArchitecture
        ? cluster.cpuArchitecture
        : common_1.CpuArchitecture.USE_DAY1_ARCHITECTURE, cluster.name, undefined, cluster.openshiftVersion);
    const bindSingleHost = (0, react_1.useCallback)((host) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
        var _a, _b;
        setIsBinding(true);
        try {
            yield HostsService_1.default.bind(host, cluster.id);
            // Binding succeeded: reset the failure counter and clear any alert that
            // was shown after previous exhausted retries.
            bindFailureCounts.current.delete(host.id);
            const alertKey = (_a = alertsRef.current.find((alert) => alert.key === host.id)) === null || _a === void 0 ? void 0 : _a.key;
            if (alertKey) {
                removeAlert(alertKey);
            }
        }
        catch (error) {
            const failureCount = ((_b = bindFailureCounts.current.get(host.id)) !== null && _b !== void 0 ? _b : 0) + 1;
            bindFailureCounts.current.set(host.id, failureCount);
            // Suppress transient errors (e.g. 5xx during self-healing) and only
            // surface the alert once silent retries have been exhausted.
            if (failureCount >= MAX_BIND_RETRY_ATTEMPTS) {
                addAlert({
                    title: `Failed to bind host ${host.requestedHostname || ''}`,
                    message: (0, utils_1.getErrorMessage)(error),
                    key: host.id,
                });
            }
        }
        finally {
            setIsBinding(false);
        }
    }), [cluster.id, addAlert, removeAlert]);
    const bindHosts = (0, react_1.useCallback)(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
        if (!infraEnvHosts || infraEnvError || infraEnvLoading || !isSingleClusterFeatureEnabled) {
            return;
        }
        for (const host of infraEnvHosts) {
            if (host.clusterId !== cluster.id) {
                yield bindSingleHost(host);
            }
        }
    }), [
        infraEnvHosts,
        infraEnvError,
        infraEnvLoading,
        isSingleClusterFeatureEnabled,
        cluster.id,
        bindSingleHost,
    ]);
    (0, react_1.useEffect)(() => {
        if (isSingleClusterFeatureEnabled) {
            void bindHosts();
        }
    }, [isSingleClusterFeatureEnabled, bindHosts]);
    return infraEnvLoading || isBinding;
};
exports.default = useLateBinding;
//# sourceMappingURL=useLateBinding.js.map