"use strict";

/**
 * private function to merge the documents
 * @param config
 * @param configDoc
 * @returns {*}
 */
function mergeDocuments(config, configDoc) {
    for(var key in configDoc) {
        if(!config.has(key)) {
            config.set(key, configDoc[key]);
        }
    }
    return config;
}

const buildClientConfigScript = (clientConfig) => 'window.ftClientConfig = ' + JSON.stringify(clientConfig) + ';';

/**
 *
 * @param conf - the configuration to merge into
 * @param databaseConfigDoc - the document that contains the configuration from the database
 * @param deferred - the promise to resolve on config load
 */
function mergeConfigs(conf, databaseConfigDoc, deferred) {
    // load the database configuration into the config. This will merge the database config into
    // the existing config according to the docs at https://github.com/mozilla/node-convict#configloadobject
    let errorMessage;
    try {
        // if the config is specified entirely in a file, there will be no database config document
        if (databaseConfigDoc) {
            // update versionId to doc.clientConfiguration, so that the version can be read on the client to
            // determine whether to update the config in local storage
            databaseConfigDoc.clientConfiguration.versionId = databaseConfigDoc.systemHeader.versionId;

            // add the clientConfiguration under serverConfiguration so calls to conf.get("clientConfiguration")
            // will work
            databaseConfigDoc.serverConfiguration.clientConfiguration = databaseConfigDoc.clientConfiguration;

            mergeDocuments(conf, databaseConfigDoc.serverConfiguration);
        }

    } catch (e) {
        errorMessage = "Error loading config from database, make sure it is valid: " + e;
        logger.error(e);
    }

    // Support deferred parameter so it can be backwards compatible with its usage at cb.
    if(deferred != null){
        logger.warn('UtilConfig.mergeConfigs > Recommended usage: No deferred parameter.');
        if(errorMessage){ // an error occurred
            deferred.reject(errorMessage);
        }else{
            deferred.resolve(conf);
        }
        return;
    }

    // Recommended usage: No deferred parameter.
    if(errorMessage){
        throw new Error(errorMessage);
    }

    return conf;

}

module.exports = {
    mergeConfigs: mergeConfigs,
    buildClientConfigScript
};
