"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.currentClusterReducer = exports.updateClusterPermissions = exports.cancelForceReload = exports.forceReload = exports.cleanCluster = exports.setServerUpdateError = exports.updateHost = exports.updateClusterBase = exports.updateCluster = exports.currentClusterSlice = exports.fetchClusterAsync = void 0;
const tslib_1 = require("tslib");
const findIndex_js_1 = tslib_1.__importDefault(require("lodash-es/findIndex.js"));
const set_js_1 = tslib_1.__importDefault(require("lodash-es/set.js"));
const toolkit_1 = require("@reduxjs/toolkit");
const utils_1 = require("../../../../common/api/utils");
const resource_ui_state_1 = require("../../../../common/types/resource-ui-state");
const ClustersService_1 = tslib_1.__importDefault(require("../../../services/ClustersService"));
exports.fetchClusterAsync = (0, toolkit_1.createAsyncThunk)('currentCluster/fetchClusterAsync', (clusterId_1, _a) => tslib_1.__awaiter(void 0, [clusterId_1, _a], void 0, function* (clusterId, { rejectWithValue }) {
    try {
        const cluster = yield ClustersService_1.default.get(clusterId);
        return cluster;
    }
    catch (e) {
        return (0, utils_1.handleApiError)(e, () => {
            return rejectWithValue({
                code: (0, utils_1.getApiErrorCode)(e),
                message: (0, utils_1.getApiErrorMessage)(e),
            });
        });
    }
}));
const initialState = {
    data: undefined,
    uiState: resource_ui_state_1.ResourceUIState.LOADING,
    permissions: { isViewerMode: false },
    errorDetail: undefined,
    isReloadScheduled: 0,
};
exports.currentClusterSlice = (0, toolkit_1.createSlice)({
    initialState,
    name: 'currentCluster',
    reducers: {
        updateClusterBase: (state, action) => {
            var _a;
            // Should not overwrite the hosts once they are created
            const originalHosts = ((_a = state.data) === null || _a === void 0 ? void 0 : _a.hosts) || [];
            return Object.assign(Object.assign({}, state), { data: Object.assign(Object.assign({}, action.payload), { hosts: originalHosts }) });
        },
        updateCluster: (state, action) => {
            return Object.assign(Object.assign({}, state), { data: action.payload });
        },
        updateHost: (state, action) => {
            var _a;
            const hostIndex = (0, findIndex_js_1.default)((_a = state.data) === null || _a === void 0 ? void 0 : _a.hosts, (host) => host.id === action.payload.id);
            if (hostIndex >= 0) {
                (0, set_js_1.default)(state, `data.hosts[${hostIndex}]`, action.payload);
            }
            return state;
        },
        setServerUpdateError: (state) => {
            return Object.assign(Object.assign({}, state), { uiState: resource_ui_state_1.ResourceUIState.UPDATE_ERROR });
        },
        cleanCluster: () => initialState,
        forceReload: (state) => (Object.assign(Object.assign({}, state), { isReloadScheduled: state.isReloadScheduled + 1 })),
        cancelForceReload: (state) => (Object.assign(Object.assign({}, state), { isReloadScheduled: 0 })),
        updateClusterPermissions: (state, action) => (Object.assign(Object.assign({}, state), { permissions: action.payload })),
    },
    extraReducers: (builder) => {
        builder
            .addCase(exports.fetchClusterAsync.pending, (state) => {
            const needsReload = state.uiState === resource_ui_state_1.ResourceUIState.LOADED ||
                (state.uiState === resource_ui_state_1.ResourceUIState.POLLING_ERROR && state.data);
            return Object.assign(Object.assign({}, state), { uiState: needsReload ? resource_ui_state_1.ResourceUIState.RELOADING : resource_ui_state_1.ResourceUIState.LOADING });
        })
            .addCase(exports.fetchClusterAsync.fulfilled, (state, action) => {
            return Object.assign(Object.assign({}, state), { data: action.payload, uiState: resource_ui_state_1.ResourceUIState.LOADED });
        })
            .addCase(exports.fetchClusterAsync.rejected, (state, action) => {
            const error = action.payload;
            if (error.code === utils_1.FETCH_ABORTED_ERROR_CODE && !!state.data) {
                // This failure is due to having aborted the request on purpose (to avoid conflicts with update operations).
                // The error can be ignored, and the data will be refreshed on the next polling
                return Object.assign(Object.assign({}, state), { uiState: resource_ui_state_1.ResourceUIState.LOADED });
            }
            return Object.assign(Object.assign({}, state), { uiState: resource_ui_state_1.ResourceUIState.POLLING_ERROR, errorDetail: error });
        });
    },
});
const { actions, reducer } = exports.currentClusterSlice;
exports.updateCluster = actions.updateCluster, exports.updateClusterBase = actions.updateClusterBase, exports.updateHost = actions.updateHost, exports.setServerUpdateError = actions.setServerUpdateError, exports.cleanCluster = actions.cleanCluster, exports.forceReload = actions.forceReload, exports.cancelForceReload = actions.cancelForceReload, exports.updateClusterPermissions = actions.updateClusterPermissions;
exports.currentClusterReducer = reducer;
//# sourceMappingURL=slice.js.map