# Source: structures/data.js

    /**
     * @file data.js
     * @module data
     * @description Contains the singleton data structure definition that allows the entire application,
     * to share data between various components of the framework and greater application platform.
     * @requires module:ruleBroker
     * @requires {@link https://www.npmjs.com/package/@haystacks/constants|@haystacks/constants}
     * @author Seth Hollingsead
     * @date 2021/10/13
     * @copyright Copyright © 2022-… by Seth Hollingsead. All rights reserved
     */

    // Internal imports
    import ruleBroker from '../brokers/ruleBroker.js';
    // External imports
    import hayConst from '@haystacks/constants';

    const {biz, msg, sys, wrd} = hayConst;
    let data = {};

    /**
     * @function getData
     * @description returns the contents of the data structure. Can be used to stash data,
     * before it is reassigned, for the purpose of setting up a unit test scenario with mocked data.
     * @return {object} A JSON object that contains all of the data that is currently stored in the data structure.
     * @author Seth Hollingsead
     * @date 2023/01/09
     */
    async function getData() {
      return {configuration: data[wrd.cconfiguration],
        businessRules: data[sys.cbusinessRules],
        Commands: data[wrd.cCommands],
        colors: data[wrd.ccolors],
        ConstantsValidationData: data[sys.cConstantsValidationData],
        CommandsAliases: data[sys.cCommandsAliases],
        CommandWorkflow: data[sys.cCommandWorkflows],
        Themes: data[wrd.cThemes]};
    }

    /**
     * @function setData
     * @description Clears the data and sets it to some new specified data.
     * Can be used to setup mock data, or create a clone of Haystacks for the purposes of
     * executing a callback on Haystacks such as loading more data for a plugin.
     * @param {object} newData The new data that should replace any data already stored on the data structure.
     * @author Seth Hollingsead
     * @date 2023/01/09
     * @NOTE This function isn't actually working, because in the haystacks code base we've
     * always set the D-data structure data on the D-object itself never on the D['data'] field.
     * So an extra special effort will need to be made to refactor the data interface again and make it work via an actual interface.
     * Instead of a hard-coded data endpoint in the code.
     * This will be a good pre-emptive step to implementing a Red-Black Binary Search Tree.
     * Because once all the data is flowing through a data interface, then we can swap out that interface for a newer faster one based on RB-BST.
     * @UPDATE Actually this function IS THE ONLY WAY this works! Setting the data on the D-object itself fails in every way.
     * I've even tried to update to node v18 and use the structuredClone function, which also didn't work.
     * But the code below DOES WORK! Don't touch it unless you want to break the loading of all plugins.
     * We can review this when we get past a production MVP release.
     * @NOTE Attempting to create/refactor for a new data interface could cause a cascade performance regression,
     * that is the last thing we want to be dealing with at this late stage in the game.
     * Perhaps we will have to wait until after a GUI system is developed, then take on this data/data-interface re-architecture and RB-BST effort all at once.
     */
    async function setData(newData) {
      // let functionName = setData.name;
      // console.log('BEGIN Haystacks.data.setData function - MANUAL LOG');
      // console.log('data input is: ' + JSON.stringify(newData));
      let returnData = false;
      if (newData) {
        data = {};
        // for (let dataEntityKey in newData) {
        //   data[dataEntityKey] = {};
        //   data[dataEntityKey] = newData[dataEntityKey];
        // }
        try {
          data = await ruleBroker.processRules([newData, ''], [biz.cobjectDeepClone]);
        } catch (err) {
          // await loggers.consoleLog(namespacePrefix + functionName, msg.cERROR_Colon + err.message);
          // ERROR: Unable to clone data and re-assign it to the D-data structure.
          console.log(msg.cErrorSetDataMessage01);
        }
        returnData = true;
      } else {
        // ERROR: Unable to set data, undefined data input:
        // console.log('ERROR: Unable to set data, undefined data input: ' + JSON.stringify(newData));
      }
      return returnData;
    }

    export default {
      [wrd.cdata]: data,
      getData,
      setData
    };