/*!
 * Copyright 2017 by ChartIQ, Inc.
 * All rights reserved.
 * The workspace management menu may be the most complicated component that we have (other than the toolbar). It isn't because workspace management is particularly difficult, it's because there is a lot of user question and answer going on. We don't want to overwrite data without explicit consent, and so the calls get involved. To simplify the code, we are using the `async` library. If you are unfamiliar with this library, see this link: https://caolan.github.io/async/docs.html
 */
import async from "async";
import { camelCase } from "../../../../../common/util";
import { FEAGlobals } from "../../../../../common/Globals";
// When a user cancels the save workspace dialog, we throw an error, which short-circuits the async call.
const SAVE_DIALOG_CANCEL_ERROR = "Cancel";
const NEGATIVE = "Negative";
let PROMPT_ON_DIRTY_WORKSPACE;
let DISCARD_UNSAVED_CHANGES;
const WORKSPACE_CONFIGS = {
    PROMPT_USER_ON_DIRTY_WORKSPACE: "finsemble.servicesConfig.workspace.promptUserOnDirtyWorkspace",
    DISCARD_UNSAVED_CHANGES: "finsemble.servicesConfig.workspace.discardUnsavedChanges",
    DEPRECATED_PROMPT_ON_DIRTY: "finsemble.preferences.workspaceService.promptUserOnDirtyWorkspace", // DEPRECATED - retrieving it for backwards compatibility
};
let WorkspaceManagementStore;
let StoreClient;
let Logger;
let WorkspaceManagementGlobalStore;
// Initial data for the store.
const defaultData = {
    activeWorkspace: {},
    menuWidth: 285,
    WorkspaceList: [],
    newWorkspaceDialogIsActive: false,
    /**
     * State around whether the workspace is currently in the process of switching.
     *
     * For simplicity, we're storing this in the local store for now, but this precludes
     * other components from signaling that the workspace is changing. A consequence,
     * for example, is that if you switch workspaces uses a pin on the toolbar instead
     * of the workspace management menu, the spinner doesn't show up.
     */
    isSwitchingWorkspaces: false,
    isPromptingUser: false,
};
function addListeners(done) {
    FEAGlobals.FSBL.Clients.RouterClient.addListener("Application.restart", (err, response) => {
        // when the user calls a "Reset" function, Finsemble shouldn't show a save workspace dialog.
        if (response.data && response.data.forceRestart === true)
            PROMPT_ON_DIRTY_WORKSPACE = false;
    });
    done();
}
const Actions = {
    autoSave: (callback) => {
        var _a;
        const activeName = ((_a = FEAGlobals.FSBL.Clients.WorkspaceClient.activeWorkspace) === null || _a === void 0 ? void 0 : _a.name) || "";
        if (!PROMPT_ON_DIRTY_WORKSPACE) {
            FEAGlobals.FSBL.Clients.WorkspaceClient.saveAs({
                name: activeName,
                force: true,
            }, (err) => {
                callback(err);
            });
        }
        else {
            callback(null);
        }
    },
    completeInitialize: () => {
        FEAGlobals.FSBL.Clients.ConfigClient.addListener({ field: WORKSPACE_CONFIGS.PROMPT_USER_ON_DIRTY_WORKSPACE }, (err, config) => {
            Logger.system.log("WorkspaceManagementStore new promptUserOnDirtyWorkspace config", config);
            PROMPT_ON_DIRTY_WORKSPACE = !!config.value;
        });
        FEAGlobals.FSBL.Clients.ConfigClient.addListener({ field: WORKSPACE_CONFIGS.DISCARD_UNSAVED_CHANGES }, (err, config) => {
            Logger.system.log("WorkspaceManagementStore new discardUnsavedChanges config", config);
            DISCARD_UNSAVED_CHANGES = !!config.value;
        });
        // Gets the workspace list and sets the value in the store.
        FEAGlobals.FSBL.Clients.WorkspaceClient.getWorkspaces((err, workspaces) => {
            Logger.system.debug("WorkspaceManagementStore init getWorkspaces", workspaces);
            WorkspaceManagementStore.set(["WorkspaceList"], workspaces);
        });
        // Get the activeWorkspace and set the value. I could have iterated through the workspaces above and found the active one, but this seems simpler.
        FEAGlobals.FSBL.Clients.WorkspaceClient.getActiveWorkspace((err, activeWorkspace) => {
            Logger.system.debug("WorkspaceManagementStore init getActiveWorkspace", activeWorkspace);
            WorkspaceManagementStore.set(["activeWorkspace"], activeWorkspace);
        });
        /**
         * We listen here for any workspace updates, and pass them to the store.
         * **NOTE**: You may notice that the signature of this callback is different from the previous ones. In this case,
         * we receive a `response`, instead of `workspaces` or `activeWorkspace`. This is because this callback is for
         * a `RouterClient` message. The functions above are callbacks to `WorkspaceClient` API calls.
         */
        FEAGlobals.FSBL.Clients.RouterClient.subscribe("Finsemble.WorkspaceService.update", (err, response) => {
            if (response.data && response.data.activeWorkspace) {
                Logger.system.debug("WorkspaceManagementStore init update", response.data);
                WorkspaceManagementStore.set(["activeWorkspace"], response.data.activeWorkspace);
                WorkspaceManagementStore.set(["WorkspaceList"], response.data.workspacesConfig);
            }
        });
        WorkspaceManagementGlobalStore.get(["owner"], (err, data) => {
            if (!window.glue42gd && data !== FEAGlobals.finsembleWindow.name)
                return;
            WorkspaceManagementGlobalStore.Dispatcher.register((action) => {
                switch (action.actionType) {
                    case "switchToWorkspace":
                        Logger.system.debug("WorkspaceManagementStore switchToWorkspace", action.data);
                        Actions.switchToWorkspace(action.data);
                        break;
                    case "reorderWorkspace":
                        Logger.system.debug("WorkspaceManagementStore reorderWorkspace", action.data);
                        Actions.reorderWorkspaceList(action.data);
                        break;
                    case "removeWorkspace":
                        Logger.system.debug("WorkspaceManagementStore removeWorkspace", action.data);
                        Actions.removeWorkspace(action.data);
                        break;
                    case "renameWorkspace":
                        Logger.system.debug("WorkspaceManagementStore renameWorkspace", action.data);
                        Actions.renameWorkspace(action.data);
                        break;
                    default:
                        // Nothing to do here
                        break;
                }
            });
        });
    },
    /*********************************************************************************************
     *
     *								GETTERS/SETTERS
     *
     *********************************************************************************************/
    getActiveWorkspace: async () => (await WorkspaceManagementStore.get(["activeWorkspace"])).data,
    // Get the name of the workspace that is currently being edited
    getWorkspaceBeingEdited: async () => (await WorkspaceManagementStore.get(["workspaceBeingEdited"])),
    getWorkspaceList: async () => { var _a; return (_a = (await WorkspaceManagementStore.get(["WorkspaceList"])).data) !== null && _a !== void 0 ? _a : []; },
    getIsSwitchingWorkspaces: async () => (await WorkspaceManagementStore.get(["isSwitchingWorkspaces"])).data,
    setIsSwitchingWorkspaces: (val) => WorkspaceManagementStore.set(["isSwitchingWorkspaces"], val),
    getIsPromptingUser: async () => (await WorkspaceManagementStore.get(["isPromptingUser"])).data,
    setIsPromptingUser: (val) => WorkspaceManagementStore.set(["isPromptingUser"], val),
    /*********************************************************************************************
     *
     *								Main Workspace Actions
     *
     *********************************************************************************************/
    /**
     * Handles the complete workflow for creating a new workspace.
     * We make sure the user doesn't lose any unsaved work, ask them to name it, make sure that workspace doesn't already exist, then actually save the new workspace. After that, we fire off a notification to let them know that everything was a great success.
     */
    newWorkspace: function () {
        let newWorkspaceName;
        Logger.system.log("New workspace - start.");
        const newWorkspaceDialogIsActive = WorkspaceManagementStore.get(["newWorkspaceDialogIsActive"]);
        // Creates the new workspace.
        const createIt = (params, cb) => {
            Logger.system.log("createIt", params);
            const { workspaceName } = params;
            FEAGlobals.FSBL.Clients.WorkspaceClient.createWorkspace(workspaceName, {}, (err, response) => {
                Logger.system.log("createIt createNewWorkspace response", workspaceName, response);
                newWorkspaceName = response.workspaceName;
                if (cb) {
                    cb(null, newWorkspaceName);
                }
            });
        };
        if (!newWorkspaceDialogIsActive) {
            WorkspaceManagementStore.set(["newWorkspaceDialogIsActive"], true);
        }
        let tasks = [
            Actions.autoSave,
            Actions.spawnWorkspaceInputField,
            Actions.validateWorkspaceInput,
            Actions.checkIfWorkspaceAlreadyExists,
            Actions.askIfUserWantsNewWorkspace,
            createIt,
        ];
        if (PROMPT_ON_DIRTY_WORKSPACE) {
            tasks = [Actions.askIfUserWantsToSave, Actions.handleSaveDialogResponse].concat(tasks);
        }
        async.waterfall(tasks, Actions.onAsyncComplete);
    },
    /**
     * Handles the workflow for removing a workspace.
     * As long as you are not deleting the workspace that is active, it will pop up a confirm dialog,
     * and if the user says "yes", it will delete the workspace.
     */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    removeWorkspace: (data, cb = (val) => { }) => {
        const workspaceName = data.name;
        const dialogParams = {
            title: "Delete this workspace?",
            question: `Are you sure you want to delete the workspace "${workspaceName}"?`,
            showNegativeButton: false,
            affirmativeResponseLabel: "Delete",
        };
        /**
         * Invoked when the user interacts with the dialog.
         */
        function onUserInput(err, response) {
            if (response.choice === "affirmative") {
                cb(true);
                FEAGlobals.FSBL.Clients.WorkspaceClient.remove({
                    name: workspaceName,
                });
            }
            else {
                cb(false);
            }
        }
        Actions.spawnDialog("YesNoDialog", dialogParams, onUserInput);
    },
    /**
     * The `activeWorkspace` is simply a copy of something we brought out of storage. This function copies the `activeWorkspace` to back to storage.
     */
    saveWorkspace: async (cb) => {
        const { data: activeWorkspace } = await WorkspaceManagementStore.get(["activeWorkspace"]);
        FEAGlobals.FSBL.Clients.WorkspaceClient.saveAs({
            force: true,
            name: activeWorkspace.name,
        }, () => {
            cb === null || cb === void 0 ? void 0 : cb(null);
        });
    },
    reorderWorkspaceList: async ({ oldIndex, newIndex }) => {
        let { data: workspaces } = await WorkspaceManagementStore.get(["WorkspaceList"]);
        workspaces = workspaces || [];
        const workspaceToMove = workspaces[oldIndex];
        workspaces.splice(oldIndex, 1);
        workspaces.splice(newIndex, 0, workspaceToMove);
        const workspacesWithExpectedStructure = workspaces === null || workspaces === void 0 ? void 0 : workspaces.map((WSName) => {
            return {
                name: WSName,
            };
        });
        FEAGlobals.FSBL.Clients.WorkspaceClient.setWorkspaceOrder({
            workspaces: workspacesWithExpectedStructure,
        }, () => { });
        WorkspaceManagementStore.set(["WorkspaceList"], workspaces);
    },
    renameWorkspace: ({ oldName, newName }) => {
        // Note: This does no checking of the workspace before renaming. If you call this function, and `newName` is an existing
        // workspace name, the existing workspace will get stomped. Currently, the UI prevents renaming to existing names.
        FEAGlobals.FSBL.Clients.WorkspaceClient.rename({
            oldName: oldName,
            newName: newName,
            removeOldWorkspace: true,
            overwriteExisting: true,
        });
    },
    showPreferences: () => {
        FEAGlobals.FSBL.Clients.LauncherClient.showWindow({
            componentType: "UserPreferences",
        }, {
            monitor: "mine",
            left: "center",
            top: "center",
        });
    },
    /**
     * Ask the user for a name, make sure it doesn't already exist, then save.
     */
    saveWorkspaceAs: () => {
        function saveIt(workspaceName, callback) {
            FEAGlobals.FSBL.Clients.WorkspaceClient.saveAs({
                name: workspaceName,
                force: true,
            }, (err, response) => {
                callback(err, response);
            });
        }
        Logger.system.log("SaveWorkspaceAs clicked.");
        async.waterfall([
            Actions.autoSave,
            Actions.spawnSaveAsDialog,
            Actions.validateWorkspaceInput,
            Actions.checkIfWorkspaceAlreadyExists,
            Actions.askAboutOverwrite,
            saveIt,
        ], Actions.onAsyncComplete);
    },
    /**
     * Asks the user if they'd like to save their data, then loads the requested workspace.
     */
    switchToWorkspace: async function ({ name }) {
        var _a;
        // if a workspace prompt is outstanding for a previous switch, immediately return to lock out user from doing another switch (until responding to prompt);
        // note this prompting flag is cleared in Actions.onAsyncComplete when the previous switch completes (after user responds to the prompt)
        const prompting = await Actions.getIsPromptingUser();
        Logger.system.log("workspaceManagementMenuStore: switchToWorkspace", prompting ? "prompting" : "not-prompting");
        if (prompting)
            return;
        Actions.setIsSwitchingWorkspaces(true);
        const { data: activeWorkspace } = await WorkspaceManagementStore.get(["activeWorkspace"]);
        /**
         * Actually perform the switch. Happens after we ask the user what they want.
         *
         */
        const switchWorkspace = (callback = () => { }) => {
            FEAGlobals.FSBL.Clients.WorkspaceClient.switchTo({
                name: name,
            }, () => {
                Actions.setIsSwitchingWorkspaces(false);
                callback();
            });
        };
        /**
         * Make sure the user is sure
         */
        const askAboutReload = (callback) => {
            Actions.spawnDialog("YesNoDialog", {
                monitor: "primary",
                title: "Save your workspace?",
                question: `\"${activeWorkspace.name}\" has unsaved changes. Would you like to save?`,
                affirmativeResponseLabel: "Save",
                negativeResponseLabel: "Don't Save",
            }, callback);
        };
        /**
         * If the workspace is dirty, we need to do more than if it's clean.
         */
        if (await FEAGlobals.FSBL.Clients.WorkspaceClient.isWorkspaceDirty()) {
            let tasks = [];
            Actions.setIsPromptingUser(true);
            let firstMethod = Actions.autoSave;
            let secondMethod = null;
            if (PROMPT_ON_DIRTY_WORKSPACE === true) {
                // We want to ask the user to save. But if they're trying to reload the workspace,
                // the message needs to be different. The first if block just switches that method.
                firstMethod = Actions.askIfUserWantsToSave;
                if (name === ((_a = FEAGlobals.FSBL.Clients.WorkspaceClient.activeWorkspace) === null || _a === void 0 ? void 0 : _a.name)) {
                    firstMethod = askAboutReload;
                }
                // If we are not autosaving, we need to process the dialog input.
                secondMethod = Actions.handleSaveDialogResponse;
            }
            if (!DISCARD_UNSAVED_CHANGES) {
                tasks = [firstMethod];
            }
            if (secondMethod) {
                tasks.push(secondMethod);
            }
            // Switch is the last thing we do.
            tasks.push(switchWorkspace);
            async.waterfall(tasks, Actions.onAsyncComplete);
        }
        else {
            switchWorkspace();
        }
    },
    /*********************************************************************************************
     *
     *								Workspace Management Helpers
     *
     *********************************************************************************************/
    /**
     * General handler for `async.series` and `async.waterfall`
     */
    onAsyncComplete(err) {
        Logger.system.debug("workspaceManagementMenuStore: onAsyncComplete");
        WorkspaceManagementStore.set(["newWorkspaceDialogIsActive"], false);
        const errMessage = err === null || err === void 0 ? void 0 : err.message;
        if (errMessage && errMessage !== NEGATIVE && errMessage !== SAVE_DIALOG_CANCEL_ERROR) {
            // handle error.
            Logger.system.error(err);
        }
        // Unlock the UI.
        Actions.setIsSwitchingWorkspaces(false);
        Actions.setIsPromptingUser(false);
    },
    /**
     * Helper for spawning dialogs. Keeps the internals of other functions squeaky clean.
     *
     * @param {string} type "YesNoDialog" or "SingleInputDialog"
     * @param {object} data Optional params for the dialog call.
     * @param {function} responseCallback invoked when the user interacts with the dialog.
     */
    spawnDialog(type, data, responseCallback) {
        Logger.system.debug("spawnDialog", type, data);
        if (type === "SingleInputDialog") {
            data.showCancelButton = true;
        }
        FEAGlobals.FSBL.Clients.DialogManager.open(type, data, responseCallback);
    },
    spawnSaveAsDialog: (cb) => {
        const onUserInput = (err, response) => {
            Logger.system.log("SpawnSaveAsDialog onUserInput", response);
            let callbackError = null;
            if (typeof err === "string") {
                // Error objects cause async to invoke the final callback in async.waterfall.
                callbackError = new Error(err);
            }
            if (cb) {
                cb(callbackError || err, response);
            }
        };
        const dialogParams = {
            title: "Enter a name for your new workspace.",
            inputLabel: "Enter a name for your new workspace.",
            affirmativeResponseLabel: "Confirm",
            showCancelButton: false,
        };
        Actions.spawnDialog("SingleInputDialog", dialogParams, onUserInput);
    },
    /**
     * Spawns an input field asking what the user would like to name their new workspace.
     */
    spawnWorkspaceInputField: (cb) => {
        // Spawns the dialog with the input field and accepts a callback to be invoked after the user acts.
        Logger.system.log("SpawnWorkspaceInput - start");
        const onUserInput = (err, response) => {
            Logger.system.log("SpawnWorkspaceInput onUserInput", response);
            let callbackError = null;
            if (typeof err === "string") {
                // Error objects cause async to invoke the final callback in async.waterfall.
                callbackError = new Error(err);
            }
            if (cb) {
                cb(callbackError || err, response);
            }
        };
        const dialogParams = {
            title: "Enter a name for your new workspace.",
            inputLabel: "Enter a name for your new workspace.",
            affirmativeResponseLabel: "Confirm",
            showCancelButton: false,
        };
        Actions.spawnDialog("SingleInputDialog", dialogParams, onUserInput);
    },
    /**
     * Asks the user if they'd like to save their workspace if it's different from what's in storage. If the workspace is clean, we just invoke the callback.
     */
    askIfUserWantsToSave: async function (callback) {
        const { data: activeWorkspace } = await WorkspaceManagementStore.get(["activeWorkspace"]);
        if (await FEAGlobals.FSBL.Clients.WorkspaceClient.isWorkspaceDirty()) {
            Logger.system.log("NewWorkspace.spawnDialog start.");
            const dialogParams = {
                monitor: "primary",
                title: "Save your workspace?",
                question: `\"${activeWorkspace.name}\" has unsaved changes. Would you like to save?`,
                affirmativeResponseLabel: "Save",
                negativeResponseLabel: "Don't Save",
            };
            const waitForUserInput = () => new Promise((resolve) => {
                const onUserInput = (err, response) => {
                    Logger.system.log("Spawn Dialog callback.");
                    if (callback)
                        callback(null, response);
                    resolve(response);
                };
                Actions.spawnDialog("YesNoDialog", dialogParams, onUserInput);
            });
            return await waitForUserInput();
        }
        else {
            // In this case the workspace is not dirty, so we don't need to save.
            if (callback)
                callback(null, { choice: "negative" });
            return { choice: "negative" };
        }
    },
    /**
     * Handles the response from the dialog asking if the user wants to save their workspace.
     *
     * @param {any} response
     * @param {any} callback
     */
    handleSaveDialogResponse(response, callback) {
        if (response.choice === "affirmative") {
            // User wants to save, so call the client API.
            Actions.saveWorkspace(callback);
        }
        else if (response.choice === "negative") {
            // Doesn't want to save.
            callback(null);
        }
        else {
            // choice === cancel
            callback(new Error(SAVE_DIALOG_CANCEL_ERROR));
        }
    },
    /**
     * Makes sure the user has input a valid workspace name.
     */
    validateWorkspaceInput(response, callback) {
        Logger.system.log("spawnWorkspaceInput", response);
        // If user wants to proceed but gave an invalid name, tell them that they messed up, then die.
        if (response.choice !== "cancel" && (!response.value || response.value === "")) {
            let dialogParams = {
                title: "Invalid Workspace Name",
                question: "Workspace names must contain letters or numbers. Please try again.",
                affirmativeResponseLabel: "OK",
                showNegativeButton: false,
                showCancelButton: false,
            };
            Actions.spawnDialog("YesNoDialog", dialogParams, () => { });
            return callback(new Error("Invalid workspace name."));
        }
        else if (response.choice === "cancel") {
            return callback(new Error(SAVE_DIALOG_CANCEL_ERROR));
        }
        callback(null, response);
    },
    askAboutOverwrite(params, callback) {
        const { workspaceExists, workspaceName } = params;
        const dialogParams = {
            title: "Overwrite Workspace?",
            question: `This will overwrite the saved data for  "${workspaceName}". Would you like to proceed?`,
            affirmativeResponseLabel: "Overwrite",
            showNegativeButton: false,
        };
        const onUserInput = (err, response) => {
            if (response.choice === "affirmative") {
                callback(null, workspaceName);
            }
            else {
                callback(new Error(NEGATIVE));
            }
        };
        if (workspaceExists) {
            Actions.spawnDialog("YesNoDialog", dialogParams, onUserInput);
        }
        else {
            callback(null, workspaceName);
        }
    },
    askIfUserWantsNewWorkspace(params, callback) {
        let { workspaceExists, workspaceName, template } = params;
        let dialogParams = {
            title: "New workspace",
            question: `The workspace "${workspaceName}" already exists. A new workspace with a modified name will be created.`,
            affirmativeResponseLabel: "OK",
            showNegativeButton: false,
        };
        function onUserInput(err, response) {
            if (response.choice === "affirmative") {
                callback(null, { workspaceName, template });
            }
            else {
                callback(new Error(NEGATIVE));
            }
        }
        if (workspaceExists) {
            Actions.spawnDialog("YesNoDialog", dialogParams, onUserInput);
        }
        else {
            callback(null, { workspaceName, template });
        }
    },
    /**
     * Checks if the workspace exists. If it does, it asks the user if they're comfortable overwriting that data.
     */
    checkIfWorkspaceAlreadyExists(response, callback) {
        const workspaceName = response.value;
        const camelCaseWorkspaceName = camelCase(workspaceName);
        // Do any of the workspaces have the same name that the user is trying to input.
        const workspaceExists = FEAGlobals.FSBL.Clients.WorkspaceClient.workspaces.some((workspace) => camelCase(workspace) === camelCaseWorkspaceName);
        callback(null, {
            workspaceExists,
            workspaceName,
            template: response.template,
        });
    },
    /*********************************************************************************************
     *
     *								Misc functionality
     *
     *********************************************************************************************/
};
function createLocalStore(done) {
    StoreClient.createStore({ store: "Finsemble-WorkspaceMenu-Local-Store", values: defaultData }, (err, store) => {
        WorkspaceManagementStore = store;
        done();
    });
}
function createGlobalStore(done) {
    StoreClient.createStore({
        store: "Finsemble-WorkspaceMenu-Global-Store",
        global: true,
        values: { owner: FEAGlobals.finsembleWindow.name },
    }, (err, store) => {
        WorkspaceManagementGlobalStore = store;
        done();
    });
}
function getPreferences(done) {
    (async () => {
        var _a, _b, _c;
        const { err: preferencesErr, data: preferencesValues } = await FEAGlobals.FSBL.Clients.ConfigClient.getPreferences();
        if (preferencesErr) {
            Logger.system.error("workspaceManagementMenuStore.getPreferences - getPreferences", preferencesErr);
        }
        let promptUserOnDirtyWorkspaceFromPreferences;
        let discardUnsavedChangesFromPreferences;
        if (preferencesValues) {
            promptUserOnDirtyWorkspaceFromPreferences = preferencesValues[WORKSPACE_CONFIGS.PROMPT_USER_ON_DIRTY_WORKSPACE];
            discardUnsavedChangesFromPreferences = preferencesValues[WORKSPACE_CONFIGS.DISCARD_UNSAVED_CHANGES];
        }
        // if we don't have a preference as a boolean value (i.e. null or undefined)
        // fetch the config to apply
        if (typeof promptUserOnDirtyWorkspaceFromPreferences !== "boolean") {
            const { err: configErr, data: configValues } = await FEAGlobals.FSBL.Clients.ConfigClient.getMultiple([
                WORKSPACE_CONFIGS.DEPRECATED_PROMPT_ON_DIRTY.split("."),
                WORKSPACE_CONFIGS.PROMPT_USER_ON_DIRTY_WORKSPACE.split("."),
            ]);
            if (configErr) {
                Logger.system.error("workspaceManagementMenuStore.getPreferences - getValues - promptUserOnDirtyWorkspace", configErr);
            }
            if (configValues) {
                // deprecated (if present) > config (fallback) > default
                PROMPT_ON_DIRTY_WORKSPACE =
                    (_b = (_a = configValues[WORKSPACE_CONFIGS.DEPRECATED_PROMPT_ON_DIRTY]) !== null && _a !== void 0 ? _a : configValues[WORKSPACE_CONFIGS.PROMPT_USER_ON_DIRTY_WORKSPACE]) !== null && _b !== void 0 ? _b : true;
            }
            else {
                // we shouldn't get to this - but in case we do we apply the default.
                PROMPT_ON_DIRTY_WORKSPACE = true;
            }
        }
        else {
            PROMPT_ON_DIRTY_WORKSPACE = promptUserOnDirtyWorkspaceFromPreferences;
        }
        // if we don't have a preference as a boolean value (i.e. null or undefined)
        // fetch the config to apply
        if (typeof discardUnsavedChangesFromPreferences !== "boolean") {
            const { err: configErr, data: configValue } = await FEAGlobals.FSBL.Clients.ConfigClient.get(WORKSPACE_CONFIGS.DISCARD_UNSAVED_CHANGES.split("."));
            if (configErr) {
                Logger.system.error("workspaceManagementMenuStore.getPreferences - getValues - discardUnsavedworkspaceChanges", configErr);
            }
            if (configValue) {
                // config (fallback) > default
                DISCARD_UNSAVED_CHANGES = (_c = configValue[WORKSPACE_CONFIGS.DISCARD_UNSAVED_CHANGES]) !== null && _c !== void 0 ? _c : false;
            }
            else {
                // we shouldn't get to this - but in case we do we assume user does not want to discard unsaved changes
                // by default.
                DISCARD_UNSAVED_CHANGES = false;
            }
        }
        else {
            DISCARD_UNSAVED_CHANGES = discardUnsavedChangesFromPreferences;
        }
        done();
    })();
}
/**
 * Initializes the store for the Workspace Management Menu.
 */
function initialize(cb) {
    StoreClient = FEAGlobals.FSBL.Clients.DistributedStoreClient;
    // eslint-disable-next-line prefer-destructuring
    Logger = FEAGlobals.FSBL.Clients.Logger;
    async.parallel([createGlobalStore, createLocalStore, getPreferences, addListeners], () => {
        Actions.completeInitialize();
        cb(WorkspaceManagementStore);
    });
}
let getStore = () => WorkspaceManagementStore;
/**
 * This is a quick little initialization manager that Terry hacked up.
 * Ultimately everything in this file should be rewritten in hooks/redux pattern.
 */
class StoreManager {
    constructor() {
        this.initialized = false;
        this.initializing = false;
        this.callbacks = [];
        this.store = null;
    }
    initialize() {
        if (this.initializing)
            return;
        this.initializing = true;
        initialize((store) => {
            this.initialized = true;
            this.store = store;
            this.callbacks.forEach((cb) => cb(store));
        });
    }
    addInitializedListener(cb) {
        if (this.initialized && this.store !== null)
            return cb(this.store);
        this.callbacks.push(cb);
    }
    removeInitializedListener(cb) {
        this.callbacks = this.callbacks.filter((entry) => entry !== cb);
    }
}
const storeManager = new StoreManager();
export { storeManager, WorkspaceManagementGlobalStore as GlobalStore, initialize, WorkspaceManagementStore as Store, Actions, getStore, };
//# sourceMappingURL=workspaceManagementMenuStore.js.map