/*
	Licensed Material - Property of IBM

	(C) Copyright 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 moduleName = 'webUpdate'; // - name for clarification during logging
//private modules
var messages = require('./externalizedStrings');
var webUpdatePath = require('./webUpdatePath');
var fileProvidedPath = require('./fileProvidedPath');
var strings = require('ibm-strings');
var errors = require('mdo-errors');
var serverSupport = require('mdo-server-support');
var platformManager = require('platform-manager');

//3rd party modules
var nopt = require('nopt');
var log = require('npmlog');
var Q = require('q');

var moduleName = 'app-webupdate';

module.exports = function (args) {
  var d = Q.defer(),
      server,
      runtime,
      password,
      serverDetails,
      updateFile,
      projectObj;

  var opts = nopt({
      'build': Boolean,
      'file': String,
      'password': String
  }, {
      '-b': '--build',
      '-f': '--file',
      '-p': '--password'
  }, args, 0);

  log.silly(moduleName, 'opts: ' + JSON.stringify(opts));

  password = opts.password ? opts.password : undefined;
  updateFile = opts.file ? opts.file : undefined;
  if(opts.argv.remain.length > 0) {
      server = opts.argv.remain[0];
      runtime = opts.argv.remain[1] ? opts.argv.remain[1] : undefined;
  }

  platformManager.detectPlatforms()
  .then(function (detectedPlatforms) {
    projectObj = detectedPlatforms;
    //Verify cordova project
    if(!projectObj.isCordova) {
      var mustBeCordovaError = errors.getError('MUSTBECORDOVAPROJECT');
      throw mustBeCordovaError;
    }
    //Process server options if we are not building only
    if(!opts.build) {
      return serverSupport.getServerDetails(server, runtime, password);
    }
  })
  .then(function (serverDetailsReturned) {
    //If --build flag was set then don't store or show server info
    if(!opts.build) {
      serverDetails = serverDetailsReturned;
      serverDetails.serverProfile.fullURL = serverDetails.serverProfile.protocol + '://' + serverDetails.serverProfile.host + ':' + serverDetails.serverProfile.port;
      strings.info(strings.format(messages.deploymentLocationMessage, serverDetails.serverProfile.fullURL, serverDetails.runtime));
    }

    if (updateFile !== undefined && opts.build) {
      var fileSpecifiedWithBuildErr = errors.getError('FILESPECIFIEDWITHBUILD');
      throw fileSpecifiedWithBuildErr;
    } else if(updateFile !== undefined && !opts.build) {
      //If file was provided then we just attempt to read it and do the webUpdate
      return fileProvidedPath(updateFile, projectObj, serverDetails);
    }  else {
      return webUpdatePath(projectObj, serverDetails, opts.build);
    }
  })
  .then(function () {
    d.resolve();
  })
  .catch(function (err) {
    var updateErr;
    //Catch a platformDetection failure
    if(projectObj === undefined) {
      updateErr = errors.getError("NOTINAVALIDPROJECT");
    } else {
      updateErr = err;
    }
    //Silly log the stack trace of the error
    if(err.stack) {
      log.silly(err.stack);
    }

    if(updateErr.message) {
      strings.fatal(strings.format(messages.webupdateFailed, updateErr.message));
    } else {
      strings.fatal(strings.format(messages.webupdateFailed, updateErr.description));
    }
    d.reject(updateErr);
  });

  return d.promise;
};
