'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _regenerator;

function _load_regenerator() {
  return _regenerator = _interopRequireDefault(require('babel-runtime/regenerator'));
}

var _bluebird;

function _load_bluebird() {
  return _bluebird = require('bluebird');
}

exports.default = installExtensions;

var _path;

function _load_path() {
  return _path = _interopRequireWildcard(require('path'));
}

var _ramda;

function _load_ramda() {
  return _ramda = _interopRequireDefault(require('ramda'));
}

var _chalk;

function _load_chalk() {
  return _chalk = _interopRequireDefault(require('chalk'));
}

var _pMapSeries;

function _load_pMapSeries() {
  return _pMapSeries = _interopRequireDefault(require('p-map-series'));
}

var _exceptions;

function _load_exceptions() {
  return _exceptions = require('../exceptions');
}

var _environment;

function _load_environment() {
  return _environment = _interopRequireDefault(require('../../environment'));
}

var _bitId;

function _load_bitId() {
  return _bitId = require('../../bit-id');
}

var _componentDependencies;

function _load_componentDependencies() {
  return _componentDependencies = _interopRequireDefault(require('../component-dependencies'));
}

var _logger;

function _load_logger() {
  return _logger = _interopRequireDefault(require('../../logger/logger'));
}

var _componentResolver;

function _load_componentResolver() {
  return _componentResolver = _interopRequireDefault(require('../../component-resolver'));
}

var _analytics;

function _load_analytics() {
  return _analytics = require('../../analytics/analytics');
}

var _;

function _load_() {
  return _ = require('..');
}

var _scopeRemotes;

function _load_scopeRemotes() {
  return _scopeRemotes = require('../scope-remotes');
}

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var removeNils = (_ramda || _load_ramda()).default.reject((_ramda || _load_ramda()).default.isNil);
function installExtensions(_ref) {
  var _this = this;

  var ids = _ref.ids,
      dependentId = _ref.dependentId,
      scope = _ref.scope,
      verbose = _ref.verbose,
      dontPrintEnvMsg = _ref.dontPrintEnvMsg;

  (_logger || _load_logger()).default.debug(`scope.installEnvironment, ids: ${ids.map(function (id) {
    return id.componentId;
  }).join(', ')}`);
  (_analytics || _load_analytics()).Analytics.addBreadCrumb('installEnvironment', `scope.installEnvironment, ids: ${(_analytics || _load_analytics()).Analytics.hashData(ids)}`);
  var componentsDir = scope.getComponentsPath();
  var isolateOpts = {
    writeBitDependencies: false,
    installPackages: true,
    noPackageJson: false,
    dist: true,
    conf: false,
    override: false,
    verbose,
    silentPackageManagerResult: true
  };
  var idsWithoutNils = removeNils(ids);
  var predicate = function predicate(id) {
    return id.componentId.toString();
  }; // TODO: should be moved to BitId class
  var uniqIds = (_ramda || _load_ramda()).default.uniqBy(predicate)(idsWithoutNils);
  var nonExistingEnvsIds = uniqIds.filter(function (id) {
    return !isEnvironmentInstalled(scope, id.componentId);
  });
  if (!nonExistingEnvsIds.length) {
    (_logger || _load_logger()).default.debug('scope.installEnvironment, all environment were successfully loaded, nothing to install');
    (_analytics || _load_analytics()).Analytics.addBreadCrumb('installEnvironment', 'scope.installEnvironment, all environment were successfully loaded, nothing to install');
    return Promise.resolve([]);
  }

  var importEnv = function () {
    var _ref2 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee(id) {
      var concreteId, concreteIds, dir, env, isolatedComponent;
      return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              concreteId = id.componentId;

              if (!id.componentId.getVersion().latest) {
                _context.next = 6;
                break;
              }

              _context.next = 4;
              return (0, (_scopeRemotes || _load_scopeRemotes()).fetchRemoteVersions)(scope, [id.componentId]);

            case 4:
              concreteIds = _context.sent;

              concreteId = concreteIds[0];

            case 6:
              (_logger || _load_logger()).default.debug(`scope.installEnvironment.importEnv, id: ${concreteId.toString()}`);

              dir = (_path || _load_path()).join(componentsDir, (_ || _load_()).Scope.getComponentRelativePath(concreteId));
              env = new (_environment || _load_environment()).default(scope, dir);
              // Destroying environment to make sure there is no left over

              _context.next = 11;
              return env.destroyIfExist();

            case 11:
              _context.next = 13;
              return env.create();

            case 13:
              _context.prev = 13;
              _context.next = 16;
              return env.isolateComponent(concreteId, isolateOpts);

            case 16:
              isolatedComponent = _context.sent;

              if (!dontPrintEnvMsg) {
                // eslint-disable-next-line no-console
                console.log((_chalk || _load_chalk()).default.bold.green(`successfully installed the ${concreteId.toString()} ${id.type}`));
              }
              return _context.abrupt('return', isolatedComponent);

            case 21:
              _context.prev = 21;
              _context.t0 = _context['catch'](13);

              if (_context.t0 instanceof (_exceptions || _load_exceptions()).ComponentNotFound) {
                _context.t0.dependentId = dependentId ? dependentId.toString() : null;
              }
              throw _context.t0;

            case 25:
            case 'end':
              return _context.stop();
          }
        }
      }, _callee, _this, [[13, 21]]);
    }));

    return function importEnv(_x) {
      return _ref2.apply(this, arguments);
    };
  }();
  return (0, (_pMapSeries || _load_pMapSeries()).default)(nonExistingEnvsIds, importEnv);
}

/**
 * sync method that loads the environment/(path to environment component)
 */
function isEnvironmentInstalled(scope, bitId) {
  (_logger || _load_logger()).default.debug(`scope.isEnvironmentInstalled, id: ${bitId.toString()}`);
  (_analytics || _load_analytics()).Analytics.addBreadCrumb('isEnvironmentInstalled', `scope.isEnvironmentInstalled, id: ${(_analytics || _load_analytics()).Analytics.hashData(bitId.toString())}`);
  if (!bitId) throw new Error('scope.isEnvironmentInstalled a required argument "bitId" is missing');
  var notFound = function notFound() {
    (_logger || _load_logger()).default.debug(`Unable to find an env component ${bitId.toString()}`);
    (_analytics || _load_analytics()).Analytics.addBreadCrumb('isEnvironmentInstalled', `Unable to find an env component ${(_analytics || _load_analytics()).Analytics.hashData(bitId.toString())}`);

    return false;
  };

  var envPath = void 0;
  try {
    envPath = (0, (_componentResolver || _load_componentResolver()).default)(bitId.toString(), null, scope.getPath());
  } catch (err) {
    return notFound();
  }
  if (!(_environment || _load_environment()).default.isEnvironmentInstalled(envPath)) return notFound();

  (_logger || _load_logger()).default.debug(`found an environment file at ${envPath}`);
  (_analytics || _load_analytics()).Analytics.addBreadCrumb('isEnvironmentInstalled', `found an environment file at ${(_analytics || _load_analytics()).Analytics.hashData(envPath)}`);
  return true;
}