"use strict";

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

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

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

  _bluebird = function () {
    return data;
  };

  return data;
}

function _uuid() {
  const data = _interopRequireDefault(require("uuid"));

  _uuid = function () {
    return data;
  };

  return data;
}

function _fsExtra() {
  const data = _interopRequireDefault(require("fs-extra"));

  _fsExtra = function () {
    return data;
  };

  return data;
}

function _path() {
  const data = _interopRequireDefault(require("path"));

  _path = function () {
    return data;
  };

  return data;
}

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

  _bitId = function () {
    return data;
  };

  return data;
}

function _constants() {
  const data = require("../constants");

  _constants = function () {
    return data;
  };

  return data;
}

function _utils() {
  const data = require("../utils");

  _utils = function () {
    return data;
  };

  return data;
}

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

  _logger = function () {
    return data;
  };

  return data;
}

function _consumer() {
  const data = require("../consumer");

  _consumer = function () {
    return data;
  };

  return data;
}

function _manyComponentsWriter() {
  const data = _interopRequireDefault(require("../consumer/component-ops/many-components-writer"));

  _manyComponentsWriter = function () {
    return data;
  };

  return data;
}

const ENV_IS_INSTALLED_FILENAME = '.bit_env_has_installed';

class Environment {
  constructor(scope, dir) {
    this.scope = scope;
    this.path = dir || _path().default.join(scope.getPath(), _constants().ISOLATED_ENV_ROOT, (0, _uuid().default)());

    _logger().default.debug(`creating a new isolated environment at ${this.path}`);
  }

  create() {
    var _this = this;

    return (0, _bluebird().coroutine)(function* () {
      yield (0, _utils().mkdirp)(_this.path);
      _this.consumer = yield _consumer().Consumer.createIsolatedWithExistingScope(_this.path, _this.scope);
    })();
  }
  /**
   * import a component end to end. Including importing the dependencies and installing the npm
   * packages.
   *
   * @param {BitId | string} bitId - the component id to isolate
   * @param {IsolateOptions} opts
   * @return {Promise.<Component>}
   */


  isolateComponent(bitId, opts) {
    var _this2 = this;

    return (0, _bluebird().coroutine)(function* () {
      // add this if statement due to extentions calling this api directly with bitId as string with version
      if (typeof bitId === 'string') {
        bitId = _bitId().BitId.parse(bitId, true);
      }

      const saveDependenciesAsComponents = opts.saveDependenciesAsComponents === undefined ? true : opts.saveDependenciesAsComponents;
      const componentsWithDependencies = yield _this2.consumer.importComponents(_bitId().BitIds.fromArray([bitId]), false, saveDependenciesAsComponents);
      const componentWithDependencies = componentsWithDependencies[0];
      const writeToPath = opts.writeToPath || _this2.path;
      const concreteOpts = {
        consumer: _this2.consumer,
        componentsWithDependencies,
        writeToPath,
        override: opts.override,
        writePackageJson: !opts.noPackageJson,
        writeConfig: opts.conf,
        writeBitDependencies: opts.writeBitDependencies,
        createNpmLinkFiles: opts.createNpmLinkFiles,
        writeDists: opts.dist,
        installNpmPackages: !!opts.installPackages,
        // convert to boolean
        installPeerDependencies: !!opts.installPackages,
        // convert to boolean
        addToRootPackageJson: false,
        verbose: opts.verbose,
        excludeRegistryPrefix: !!opts.excludeRegistryPrefix,
        silentPackageManagerResult: opts.silentPackageManagerResult
      };
      const manyComponentsWriter = new (_manyComponentsWriter().default)(concreteOpts);
      yield manyComponentsWriter.writeAll();
      yield Environment.markEnvironmentAsInstalled(writeToPath);
      return componentWithDependencies;
    })();
  }
  /**
   * It helps to make sure an environment is installed. Otherwise, in case a user interrupts the environment
   * installation process, it won't be installed again.
   */


  static markEnvironmentAsInstalled(dir) {
    const filePath = _path().default.join(dir, ENV_IS_INSTALLED_FILENAME);

    return (0, _utils().outputFile)({
      filePath,
      content: ''
    });
  }

  static isEnvironmentInstalled(dir) {
    const filePath = _path().default.join(dir, ENV_IS_INSTALLED_FILENAME);

    return _fsExtra().default.existsSync(filePath);
  }

  getPath() {
    return this.path;
  }

  destroy() {
    _logger().default.debug(`destroying the isolated environment at ${this.path}`);

    _logger().default.info(`environment, deleting ${this.path}`);

    return _fsExtra().default.remove(this.path);
  }

  destroyIfExist() {
    var _this3 = this;

    return (0, _bluebird().coroutine)(function* () {
      const isExist = yield _fsExtra().default.exists(_this3.path);

      if (isExist) {
        _logger().default.debug(`destroying existing environment in path ${_this3.path}`);

        return _this3.destroy();
      }

      return false;
    })();
  }

}

exports.default = Environment;