/*
	Licensed Material - Property of IBM

	(C) Copyright 2015 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 fs = require('fs');
var q = require('q');
var path = require('path');
var home = require('user-home');
var log = require('npmlog');
var strings = require('ibm-strings');
var messages = strings({locales:path.resolve(__dirname, '..', 'nls')});
var errors = require('mdo-errors');
var mkdirp = require('mkdirp');
var defaultKeys = require("./global_keys.json");
var EXIT_INTERACTIVE = "finished_exit";
var MFP_HOME = path.join(String(home), ".ibm", "mobilefirst");

// we cannot initialize this now because MDO_CLI_FULL_VERSION is not yet set
var pathToConfig;
// initialize and return pathToConfig - all access to pathToConfig should
// be done through this getter
function getPathToConfig() {
  if(!pathToConfig) {
    pathToConfig = path.join(MFP_HOME, global.MDO_CLI_FULL_VERSION, "config_cli.json");
  }
  return pathToConfig;
}

//constants to be used for each key
//only used with getValueForKey and setValueForKey
var keys = {
  DEVELOPMENT_BROWSER : "development_browser",
  DEFAULT_PREVIEW_TYPE : "default_preview_type"
};

//constants for values in keys that are not user inputted
//values are used in the value fields for the getters.
var values = {
  DEFAULT_BROWSER : "default",
  SIMPLE_BROWSER : "browser",
  MBS : "mbs"
};

/*
 * Verifies if the config_cli.json file exists
 * if not then it creates one with default values
 * Is ran everytime you try to get or set a value.
 */
var verifyConfig = function(){
  var def = q.defer();

  copyOldConfig().then(function() {
    try{
      //no error so the file exists and the values are taken from it.
      log.verbose(messages.verifyConfig,messages.foundConfig);
      //will throw an error during parse if incorrectly formatted.
      var userKeys = JSON.parse(fs.readFileSync(getPathToConfig()));

      log.silly(messages.verifyConfig,strings.format(messages.configValues, JSON.stringify(userKeys)));
      def.resolve(userKeys);
    }catch(err){
      log.verbose(messages.verifyConfig,messages.configNotFound);
      if(err.code === 'ENOENT'){
        userKeys = {};
        for (var k in defaultKeys) {
          if (defaultKeys[k].value !== EXIT_INTERACTIVE) {
            userKeys[k] = {value: defaultKeys[k].default};
          }
        }
        log.verbose(messages.verifyConfig, messages.createdConfig);
        //makes all parent folders for this file if they are missing.
        //~/.ibm/mobilefirst/<platform version>/config_cli.json
        mkdirp(path.dirname(getPathToConfig()), function (err) {
            if(err)def.reject(errors.getError('CANNOTVERIFYCONFIG', err));
            else{
              fs.writeFileSync(getPathToConfig(), JSON.stringify(userKeys, null, 2), 'utf8');
              def.resolve(userKeys);
            }
        });
      }else{
        strings.fatal(errors.getError('CANNOTVERIFYCONFIG', err).description);
        def.reject(errors.getError('CANNOTVERIFYCONFIG', err));
      }
    }
  });


  return def.promise;
};

//getters for the keys
var getValueForKey = function(key){
  return verifyConfig().then(function(userKeys){
    return userKeys[key].value;
  }, function(err){
    return err;
  });
};
var getDevelopmentBrowser = function(){
  return getValueForKey(keys.DEVELOPMENT_BROWSER).then(function(val){
    return val;
  });
};
var getDefaultPreviewType = function(){
  return getValueForKey(keys.DEFAULT_PREVIEW_TYPE).then(function(val){
    return val;
  });
};

//setters for the key values
var setValueForKey = function(key, val){
  return verifyConfig().then(function(userKeys){
    userKeys[key].value = val;
    fs.writeFileSync(pathToConfig, JSON.stringify(userKeys, null, 2), 'utf8');
    return true;
  }, function(err){
    return err;
  });
};

var setDevelopmentBrowser = function(val){
  return setValueForKey(keys.DEVELOPMENT_BROWSER, val);
};

var setDefaultPreviewType = function(val){
  return setValueForKey(keys.DEFAULT_PREVIEW_TYPE, val);
};

function copyOldConfig() {
  var def = q.defer();
  try{
    if(!fs.existsSync(getPathToConfig())) {
      // Check if older version of CLI to copy this file from
      var mfpVersions = fs.readdirSync(MFP_HOME);
      var previousVersion = null;
      for(var i in mfpVersions) {
        if(fs.existsSync(path.join(MFP_HOME, mfpVersions[i], 'config_cli.json'))) {
          if(mfpVersions[i].substring(0,1) === global.MDO_CLI_FULL_VERSION.substring(0,1)) {
            previousVersion = path.join(MFP_HOME, mfpVersions[i], 'config_cli.json');
          }
        }
      }
      if (previousVersion) {
        var userKeys = JSON.parse(fs.readFileSync(previousVersion));
        fs.writeFileSync(getPathToConfig(), JSON.stringify(userKeys, null, 2), 'utf8');
      }
    }
  } catch(err) {
    strings.fatal(errors.getError('CANNOTVERIFYCONFIG', err).description);
    def.reject(errors.getError('CANNOTVERIFYCONFIG', err));
  }
  def.resolve();
  return def.promise;
}

module.exports = {
  keys: keys,
  values: values,
  getDevelopmentBrowser: getDevelopmentBrowser,
  getDefaultPreviewType: getDefaultPreviewType,
  getValueForKey: getValueForKey,
  setDevelopmentBrowser: setDevelopmentBrowser,
  setDefaultPreviewType: setDefaultPreviewType,
  setValueForKey: setValueForKey,
  verifyConfig: verifyConfig
};
