Source: lib/init/runtime.js

'use strict';
// const path = require('path');
// const fs = require('fs-extra');
const minimist = require('minimist');

/**
 * get the application environment from command line arguments
 * 
 * @param {any} argv parsed command line arguments
 * @returns {string|boolean} returns the value of the enviroment or false
 */
function getEnv(argv) {
  if (!argv && !process.env.NODE_ENV && !process.env.ENV) {
    return false;
  } else if (argv && argv.e) {
    return argv.e;
  } else if (argv && argv._ && argv._.length === 1) {
    return argv._[0];
  } else if (process.env.NODE_ENV) {
    return process.env.NODE_ENV;
  } else if (process.env.ENV) {
    return process.env.ENV;
  } else {
    return false;
  }
}

/**
 * sets the application runtime environment and save last run environment into configuration
 * 
 * @param {any} env this is the enviroment variable to set
 * @param {string} operation either update the config db, or create a new entry for process.runtime
 * @param {object} processRuntimeConfig existing runtime config from configuration database
 * @returns {boolean|Promise} returns a resolved promise after configuration database operation
 */
function setAppRunningEnv(env, operation, processRuntimeConfig, argv = {}) {
  // console.log({ env, operation, processRuntimeConfig })
  const processEnv = {
    process: {
      runtime: env,
    },
  };
  const configProcessEnv = Object.assign({}, processEnv);
  configProcessEnv.process = Object.assign({}, configProcessEnv.process, {
    cli: (argv.cli) ? true : false,
    argv,
  });
  const processConfig = {
    filepath: 'content/config/process/runtime.json', // environment: String,  // container: String,
    config: processEnv,
  };
  this.config = Object.assign({}, this.config, configProcessEnv);
  if (argv.debug) {
    this.config.debug = (argv.debug === false || argv.debug === 'false') ? false : argv.debug;
  }
  if (argv.crud || argv.createConfig || argv.cco || argv.addConfig || argv.aco || argv.removeConfig || argv.rco || argv.createExtension || argv.addExtension || argv.aex || argv.removeExtension || argv.rex || argv.createContainer) {
    this.config.process.skip_external_resources = true;
  }
  // console.log('this.config', this.config);
  if (operation === 'update') {
    const updateDoc = Object.assign({}, processRuntimeConfig, processConfig);
    // console.log({ updateDoc });
    return this.configuration.update({ updatedoc: updateDoc, });
  } else if (operation === 'create') {
    return this.configuration.create({
      newdoc: processConfig,
    });
  } else return false;
}

/**
 * sets the runtime environment correctly, there are multiple ways to set the runtime environment (via command line arguments, or via environment variables)
 * It will prioritize loading via command line argument first, and then environment variables, and finally it will use the last runtime environment
 * 
 * @returns {Promise} configRuntimeEnvironment sets up application config db
 */
function configRuntimeEnvironment() {
  const setAppEnv = setAppRunningEnv.bind(this);
  return new Promise((resolve, reject) => {
    try {
      // console.log('process.argv', process.argv);
      // console.log('configRuntimeEnvironment this.config', this.config);
      const argv = require('minimist')(process.argv.slice(2));
      const appEnv = this.config.environment || getEnv(argv);
      let existingRuntimeEnv;
      // if (this.config.configuration.type === 'db') {
      this.configuration.load({ docid: 'filepath', query: 'content/config/process/runtime.json', })
        .then(result => {
          try {
            existingRuntimeEnv = result.config.process.runtime;
          } catch (e) {
            existingRuntimeEnv = false;
          }
          // console.log({ result,appEnv,existingRuntimeEnv });
          if (!result && !appEnv && !existingRuntimeEnv) {
            throw new Error('A valid runtime environment is required');
          }
          if (result) {
            if (result.toJSON && typeof result.toJSON === 'function') {
              result = result.toJSON();
            }
            if (existingRuntimeEnv === appEnv) {
              resolve(setAppEnv(appEnv, undefined, undefined, argv));
            } else {
              resolve(setAppEnv(appEnv || existingRuntimeEnv, 'update', result, argv));
            }
          } else {
            resolve(setAppEnv(appEnv, 'create', undefined, argv));
          }
        })
        .catch(reject);
      // } else { //eventually handle files again
      // const __CONFIG_DIR = path.resolve(this.config.app_root, 'content/config');
      // const __CONFIG_JSON_PATH = path.join(__CONFIG_DIR, 'config.json');
      // }
    } catch (e) {
      reject(e);
    }
  });
}

function completeInitialization(resolve, reject, e) {
  if (e.message === 'Leave Promise Chain: CLI Process' ||
    e.message === 'Leave Promise Chain: Forking Process') {
    this.logger.info(e.message);
    resolve(true);
  } else {
    this.logger.error('Could not initialize Periodic');
    reject(e);
  }
}

module.exports = {
  configRuntimeEnvironment,
  getEnv,
  setAppRunningEnv,
  completeInitialization,
};