"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

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

function _bluebird() {
  const data = require("bluebird");

  _bluebird = function () {
    return data;
  };

  return data;
}

function pathLib() {
  const data = _interopRequireWildcard(require("path"));

  pathLib = function () {
    return data;
  };

  return data;
}

function _ramda() {
  const data = _interopRequireDefault(require("ramda"));

  _ramda = function () {
    return data;
  };

  return data;
}

function _chalk() {
  const data = _interopRequireDefault(require("chalk"));

  _chalk = function () {
    return data;
  };

  return data;
}

function _pMapSeries() {
  const data = _interopRequireDefault(require("p-map-series"));

  _pMapSeries = function () {
    return data;
  };

  return data;
}

function _exceptions() {
  const data = require("../exceptions");

  _exceptions = function () {
    return data;
  };

  return data;
}

function _environment() {
  const data = _interopRequireDefault(require("../../environment"));

  _environment = function () {
    return data;
  };

  return data;
}

function _bitId() {
  const data = require("../../bit-id");

  _bitId = function () {
    return data;
  };

  return data;
}

function _componentDependencies() {
  const data = _interopRequireDefault(require("../component-dependencies"));

  _componentDependencies = function () {
    return data;
  };

  return data;
}

function _logger() {
  const data = _interopRequireDefault(require("../../logger/logger"));

  _logger = function () {
    return data;
  };

  return data;
}

function _componentResolver() {
  const data = _interopRequireDefault(require("../../component-resolver"));

  _componentResolver = function () {
    return data;
  };

  return data;
}

function _analytics() {
  const data = require("../../analytics/analytics");

  _analytics = function () {
    return data;
  };

  return data;
}

function _() {
  const data = require("..");

  _ = function () {
    return data;
  };

  return data;
}

function _scopeRemotes() {
  const data = require("../scope-remotes");

  _scopeRemotes = function () {
    return data;
  };

  return data;
}

const removeNils = _ramda().default.reject(_ramda().default.isNil);

function installExtensions({
  ids,
  dependentId,
  scope,
  verbose,
  dontPrintEnvMsg
}) {
  _logger().default.debug(`scope.installEnvironment, ids: ${ids.map(id => id.componentId).join(', ')}`);

  _analytics().Analytics.addBreadCrumb('installEnvironment', `scope.installEnvironment, ids: ${_analytics().Analytics.hashData(ids)}`);

  const componentsDir = scope.getComponentsPath();
  const isolateOpts = {
    writeBitDependencies: false,
    installPackages: true,
    noPackageJson: false,
    dist: true,
    conf: false,
    override: false,
    verbose,
    silentPackageManagerResult: true
  };
  const idsWithoutNils = removeNils(ids);

  const predicate = id => id.componentId.toString(); // TODO: should be moved to BitId class


  const uniqIds = _ramda().default.uniqBy(predicate)(idsWithoutNils);

  const nonExistingEnvsIds = uniqIds.filter(id => {
    return !isEnvironmentInstalled(scope, id.componentId);
  });

  if (!nonExistingEnvsIds.length) {
    _logger().default.debug('scope.installEnvironment, all environment were successfully loaded, nothing to install');

    _analytics().Analytics.addBreadCrumb('installEnvironment', 'scope.installEnvironment, all environment were successfully loaded, nothing to install');

    return Promise.resolve([]);
  }

  const importEnv =
  /*#__PURE__*/
  function () {
    var _ref = (0, _bluebird().coroutine)(function* (id) {
      let concreteId = id.componentId;

      if (id.componentId.getVersion().latest) {
        const concreteIds = yield (0, _scopeRemotes().fetchRemoteVersions)(scope, [id.componentId]);
        concreteId = concreteIds[0];
      }

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

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

      yield env.destroyIfExist();
      yield env.create();

      try {
        const isolatedComponent = yield env.isolateComponent(concreteId, isolateOpts);

        if (!dontPrintEnvMsg) {
          // eslint-disable-next-line no-console
          console.log(_chalk().default.bold.green(`successfully installed the ${concreteId.toString()} ${id.type}`));
        }

        return isolatedComponent;
      } catch (e) {
        if (e instanceof _exceptions().ComponentNotFound) {
          e.dependentId = dependentId ? dependentId.toString() : null;
        }

        throw e;
      }
    });

    return function importEnv(_x) {
      return _ref.apply(this, arguments);
    };
  }();

  return (0, _pMapSeries().default)(nonExistingEnvsIds, importEnv);
}
/**
 * sync method that loads the environment/(path to environment component)
 */


function isEnvironmentInstalled(scope, bitId) {
  _logger().default.debug(`scope.isEnvironmentInstalled, id: ${bitId.toString()}`);

  _analytics().Analytics.addBreadCrumb('isEnvironmentInstalled', `scope.isEnvironmentInstalled, id: ${_analytics().Analytics.hashData(bitId.toString())}`);

  if (!bitId) throw new Error('scope.isEnvironmentInstalled a required argument "bitId" is missing');

  const notFound = () => {
    _logger().default.debug(`Unable to find an env component ${bitId.toString()}`);

    _analytics().Analytics.addBreadCrumb('isEnvironmentInstalled', `Unable to find an env component ${_analytics().Analytics.hashData(bitId.toString())}`);

    return false;
  };

  let envPath;

  try {
    envPath = (0, _componentResolver().default)(bitId.toString(), null, scope.getPath());
  } catch (err) {
    return notFound();
  }

  if (!_environment().default.isEnvironmentInstalled(envPath)) return notFound();

  _logger().default.debug(`found an environment file at ${envPath}`);

  _analytics().Analytics.addBreadCrumb('isEnvironmentInstalled', `found an environment file at ${_analytics().Analytics.hashData(envPath)}`);

  return true;
}