'use strict';

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

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _path;

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

var _driverNotFound;

function _load_driverNotFound() {
  return _driverNotFound = _interopRequireDefault(require('./exceptions/driver-not-found'));
}

var _constants;

function _load_constants() {
  return _constants = require('../constants');
}

var _logger;

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

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

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Driver = function () {
  function Driver() {
    var lang = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : (_constants || _load_constants()).DEFAULT_LANGUAGE;

    _classCallCheck(this, Driver);

    this.lang = lang;
  }

  _createClass(Driver, [{
    key: 'driverName',
    value: function driverName() {
      return this.lang.startsWith('bit-') ? this.lang : `bit-${this.lang}`;
    }
  }, {
    key: 'getDriver',
    value: function getDriver() {
      var silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;

      if (this.driver) return this.driver;
      var langDriver = this.driverName();
      try {
        this.driver = require(langDriver);
        return this.driver;
      } catch (err) {
        (_logger || _load_logger()).default.error('failed to get the driver', err);
        if (silent) return undefined;
        if (err.code !== 'MODULE_NOT_FOUND' && err.message !== 'missing path') throw err;
        throw new (_driverNotFound || _load_driverNotFound()).default(langDriver, this.lang);
      }
    }
  }, {
    key: 'runHook',
    value: function runHook(hookName, param, returnValue) {
      var driver = this.getDriver();
      // $FlowFixMe
      if (!driver || !driver.lifecycleHooks || !driver.lifecycleHooks[hookName]) {
        if (!driver) (_logger || _load_logger()).default.info('unable to find a driver, the hooks will be ignored');else (_logger || _load_logger()).default.info(`the driver doesn't implement ${hookName} hook`);
        return Promise.resolve(returnValue); // it's ok for a driver to not implement a hook
      }

      return driver.lifecycleHooks[hookName](param).then(function () {
        return returnValue;
      });
    }

    // TODO: Improve flow object return type

  }, {
    key: 'getDependencyTree',
    value: function getDependencyTree(cwd, consumerPath, filePaths, bindingPrefix, resolveModulesConfig) {
      // This is important because without this, madge won't know to resolve files if we run the
      // CMD not from the root dir
      var fullPaths = filePaths.map(function (filePath) {
        return (_path || _load_path()).default.join(cwd, filePath);
      });
      var driver = this.getDriver(false);

      return driver.getDependencyTree({
        baseDir: cwd,
        consumerPath,
        filePaths: fullPaths,
        bindingPrefix,
        resolveModulesConfig
      });
    }

    // TODO: Improve flow object return type

  }, {
    key: 'npmLogin',
    value: function npmLogin(token, npmrcPath, registryUrl) {
      var driver = this.getDriver(false);
      return driver.npmLogin(token, npmrcPath, registryUrl);
    }
  }], [{
    key: 'load',
    value: function load(lang) {
      return new Driver(lang);
    }
  }]);

  return Driver;
}();

exports.default = Driver;