"use strict";

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

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

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

  _path = function () {
    return data;
  };

  return data;
}

function _bitJavascript() {
  const data = _interopRequireDefault(require("bit-javascript"));

  _bitJavascript = function () {
    return data;
  };

  return data;
}

function _driverNotFound() {
  const data = _interopRequireDefault(require("./exceptions/driver-not-found"));

  _driverNotFound = function () {
    return data;
  };

  return data;
}

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

  _constants = function () {
    return data;
  };

  return data;
}

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

  _logger = function () {
    return data;
  };

  return data;
}

class Driver {
  constructor(lang = _constants().DEFAULT_LANGUAGE) {
    this.lang = lang;
  }

  driverName() {
    return this.lang.startsWith('bit-') ? this.lang : `bit-${this.lang}`;
  }

  getDriver(silent = true) {
    if (this.driver) return this.driver;
    const langDriver = this.driverName();

    if (langDriver === 'bit-javascript') {
      this.driver = _bitJavascript().default;
    } else {
      try {
        this.driver = require(langDriver);
      } catch (err) {
        _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().default)(langDriver, this.lang);
      }
    }

    return this.driver;
  }

  runHook(hookName, param, returnValue) {
    const driver = this.getDriver(); // $FlowFixMe

    if (!driver || !driver.lifecycleHooks || !driver.lifecycleHooks[hookName]) {
      if (!driver) _logger().default.info('unable to find a driver, the hooks will be ignored');else _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(() => returnValue);
  } // TODO: Improve flow object return type


  getDependencyTree(cwd, consumerPath, filePaths, bindingPrefix, resolveModulesConfig, cacheResolvedDependencies, cacheProjectAst) {
    // This is important because without this, madge won't know to resolve files if we run the
    // CMD not from the root dir
    const fullPaths = filePaths.map(filePath => _path().default.join(cwd, filePath));
    const driver = this.getDriver(false); // $FlowFixMe driver must be set

    return driver.getDependencyTree({
      baseDir: cwd,
      consumerPath,
      filePaths: fullPaths,
      bindingPrefix,
      resolveModulesConfig,
      visited: cacheResolvedDependencies,
      cacheProjectAst
    });
  } // TODO: Improve flow object return type


  npmLogin(token, npmrcPath, registryUrl) {
    const driver = this.getDriver(false);
    return driver.npmLogin(token, npmrcPath, registryUrl);
  }

  static load(lang) {
    return new Driver(lang);
  }

}

exports.default = Driver;