/*
	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';

//private modules
var encryptWWWFolder = require('mdo-cordova-support').encryptWWWFolder;
var errors = require('mdo-errors');
var platformManager = require('platform-manager');
var strings = require('ibm-strings');
var messages = require('./externalizedStrings');

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

var moduleName = 'encrypt'; // - name for clarification during logging

module.exports = function encrypt() {
    var d = Q.defer(),
        projectObj,
        filteredPlatforms,
        encryptPromises = [],
        windowsNotSupportedMessageShown = false,
        browserNotSupportedMessageShown = false;

    platformManager.detectPlatforms()
    .then(function (detectedProjectInfo) {
      log.silly(moduleName, 'detect Project: ' + JSON.stringify(detectedProjectInfo));
      projectObj = detectedProjectInfo;

      //Verify cordova project
      if(!projectObj.isCordova) {
        var mustBeCordovaError = errors.getError('MUSTBECORDOVAPROJECT');
        throw mustBeCordovaError;
      }

      //Filter out Windows and browser and display a 'platform unsupported' message only once
      log.silly(moduleName, 'filtering out Windows and browser platforms');
      filteredPlatforms = projectObj.platforms.filter(function (el) {
        if(el.platform.indexOf('windows') >= 0 && !windowsNotSupportedMessageShown) {
          var windowsNotSupportedErr = errors.getError("WINDOWSNOTSUPPORTEDWEBUPDATE", 'windows');
          strings.warn(windowsNotSupportedErr.description);
          windowsNotSupportedMessageShown = true;
        } else if(el.platform.indexOf('browser') >= 0 && !browserNotSupportedMessageShown) {
            var browserNotSupportedErr = errors.getError("BROWSERNOTSUPPORTEDWEBUPDATE", 'browser');
            strings.warn(browserNotSupportedErr.description);
            browserNotSupportedMessageShown = true;
        }
        return el.platform.indexOf('windows') < 0 && el.platform.indexOf('browser') < 0;
      });

      log.silly(moduleName, 'filteredPlatforms: ' + JSON.stringify(filteredPlatforms));
      filteredPlatforms.forEach(function (platform) {
        encryptPromises.push(encryptPlatform(platform, projectObj.rootDir));
      });
      return Q.all(encryptPromises);
    })
    .then(function () {
      d.resolve();
    })
    .catch(function (err) {
      log.silly(err.stack);
      strings.fatal(err.description);
      d.reject(err);
    });

    return d.promise;
};

function encryptPlatform(platformObj, configXMLDir) {
  var chunked = '',
      encryptPathArg,
      d = Q.defer();

  log.silly(moduleName, 'Encrypting www folder for platform: ' + platformObj.platform);
  if(platformObj.platform === 'android') {
    encryptPathArg = path.resolve(configXMLDir, 'platforms', 'android', 'assets', 'www');
    chunked = '--chunk';
  } else if (platformObj.platform === 'ios') {
    encryptPathArg = path.resolve(configXMLDir, 'platforms', 'ios', 'www');
  }

  if(pathAlreadyEncrypted(encryptPathArg)) {
    strings.info(strings.format(messages.alreadyEncrypted, platformObj.platform));
    d.resolve();
  } else {
    var encryptArgs = ['--path', encryptPathArg, chunked];

    log.silly(moduleName, 'Encrypting, encryptArgs: ' + encryptArgs);
    encryptWWWFolder(configXMLDir, encryptArgs)
    .then(function () {
      strings.info(strings.format(messages.encryptedPlatform, platformObj.platform));
      d.resolve();
    }, function (err) {
      log.silly(moduleName, 'Encrypt failed for platform: ' + platformObj.platform);
      if(!isNaN(err.code) && err.code !== 0) {
        err = errors.getError('ERRORDURINGEXTERNALSCRIPT', platformObj.platform);
      }
      d.reject(err);
    });
  }

  return d.promise;
}

function pathAlreadyEncrypted(encryptPathArg) {
  var encrypted = true;

  log.silly(moduleName, 'Checking if files in \'' + encryptPathArg + ' are already encrypt (resources.zip');
  var folderContents = fs.readdirSync(encryptPathArg);
  folderContents.forEach(function (content) {
    log.silly(moduleName, 'File found: ' + content);
    if(!content.match('resources.zip')) {
      encrypted = false;
    }
  });

  return encrypted;
}
