/*
	Licensed Material - Property of IBM

	(C) Copyright 2015, 2016 IBM Corp.

	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
*/


'use strict';

var Q = require('q');

var os = require('os');
var path = require('path');

module.exports.run = function( /*argv*/ ) {
  var deferred = Q.defer();

  // print stock information I know about personally
  printSystemInfo();

  // gather up extensions to mdo.cli.info and print those
  printExtendedInfo().then(function() {
    deferred.resolve();
  });

  return deferred.promise;
};

module.exports.help = function(/*argv*/) {
  var fs = require('fs');

  var deferred = Q.defer();

  fs.readFile(path.resolve(__dirname, '..', 'help', 'help.txt'), {
    encoding: 'utf8'
  }, function(err, data) {
    if (err) {
      deferred.reject(err);
    } else {
      console.log(data);
      deferred.resolve();
    }
  });

  return deferred.promise;
};

function printSystemInfo() {
  var messages = require('./externalizedStrings');

  var mb = Math.pow(2, 20);
  console.log(messages.os + process.platform + ' ' + process.arch);
  console.log(messages.os_version + os.release());
  console.log(messages.system_memory + Math.floor(os.freemem() / mb) + ' MB free out of ' + Math.floor(os.totalmem() / mb) + ' MB');
  console.log(messages.cwd + process.cwd());

  console.log('');

  console.log(messages.node + process.version);
  console.log(messages.cli + global.MDO_CLI_FULL_VERSION);

  console.log('');

  console.log(messages.env_vars);
  for (var key in process.env) {
    console.log('  ' + key + ': ' + process.env[key]);
  }
}

// run iterator function over all elements in the array, ensuring
// that the asynchronous iterator function runs in array order
function mapSeries(arr, iterator) {
  // create a empty promise to start our series (so we can use `then`)
  var currentPromise = new Q();
  var promises = arr.map(function(el) {
    return currentPromise = currentPromise.then(function() {
      // execute the next function after the previous has resolved successfully
      return iterator(el);
    });
  });
  // group the results and return the group promise
  return Q.all(promises);
}

function printExtendedInfo() {
  var deferred = Q.defer();

  var findExtensions = require('pluggington');

  // this is a little weird to look up outside of this module, but then it allows
  // info contributors to be placed under the same folder as command contributors
  var extendedInfoContribs = findExtensions(global.MDO_MAIN_EXTENSIONS_PATH, 'mdo.cli.info');

  if (extendedInfoContribs) {
    // TODO first sort these... somehow
    mapSeries(extendedInfoContribs, function(extension) {
      return extension.export.printInfo();
    });
  }

  return deferred.promise;
}
