"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 _defineProperty2() {
  const data = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

  _defineProperty2 = function () {
    return data;
  };

  return data;
}

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

  _ramda = function () {
    return data;
  };

  return data;
}

function _abstractConfig() {
  const data = _interopRequireDefault(require("./abstract-config"));

  _abstractConfig = function () {
    return data;
  };

  return data;
}

function _generalError() {
  const data = _interopRequireDefault(require("../../error/general-error"));

  _generalError = function () {
    return data;
  };

  return data;
}

function _filterObject() {
  const data = _interopRequireDefault(require("../../utils/filter-object"));

  _filterObject = function () {
    return data;
  };

  return data;
}

function _packageJsonFile() {
  const data = _interopRequireDefault(require("../component/package-json-file"));

  _packageJsonFile = function () {
    return data;
  };

  return data;
}

class ComponentConfig extends _abstractConfig().default {
  constructor({
    compiler,
    tester,
    lang,
    bindingPrefix,
    extensions,
    overrides
  }) {
    super({
      compiler,
      tester,
      lang,
      bindingPrefix,
      extensions
    });
    (0, _defineProperty2().default)(this, "componentHasWrittenConfig", false);
    this.overrides = overrides;
    this.writeToBitJson = true; // will be changed later to work similar to workspace-config
  }

  toPlainObject() {
    const superObject = super.toPlainObject();

    const componentObject = _ramda().default.merge(superObject, {
      overrides: this.overrides
    });

    const isPropDefaultOrEmpty = (val, key) => {
      if (key === 'overrides') return !_ramda().default.isEmpty(val);
      return true;
    };

    return (0, _filterObject().default)(componentObject, isPropDefaultOrEmpty);
  }

  validate(bitJsonPath) {
    if (typeof this.compiler !== 'object' || typeof this.tester !== 'object' || this.extensions() && typeof this.extensions() !== 'object') {
      throw new (_generalError().default)(`bit.json at "${bitJsonPath}" is invalid, re-import the component with "--conf" flag to recreate it`);
    }
  }

  static fromPlainObject(object) {
    const {
      env,
      lang,
      bindingPrefix,
      extensions,
      overrides
    } = object;
    return new ComponentConfig({
      compiler: _ramda().default.prop('compiler', env),
      tester: _ramda().default.prop('tester', env),
      extensions,
      lang,
      bindingPrefix,
      overrides
    });
  }

  static fromComponent(component) {
    return new ComponentConfig({
      version: component.version,
      scope: component.scope,
      lang: component.lang,
      bindingPrefix: component.bindingPrefix,
      compiler: component.compiler || {},
      tester: component.tester || {},
      overrides: component.overrides.componentOverridesData
    });
  }

  mergeWithComponentData(component) {
    this.bindingPrefix = this.bindingPrefix || component.bindingPrefix;
    this.lang = this.lang || component.lang;
  }
  /**
   * Use the workspaceConfig as a base. Override values if exist in componentConfig
   */


  static mergeWithWorkspaceConfig(componentConfig, consumerConfig) {
    const plainConsumerConfig = consumerConfig ? consumerConfig.toPlainObject() : {};
    return ComponentConfig.fromPlainObject(_ramda().default.merge(plainConsumerConfig, componentConfig));
  }
  /**
   * component config is written by default to package.json inside "bit" property.
   * in case "eject-conf" was running or the component was imported with "--conf" flag, the
   * bit.json is written as well.
   *
   * @param {*} componentDir root component directory, needed for loading package.json file.
   * in case a component is authored, leave this param empty to not load the project package.json
   * @param {*} configDir dir where bit.json and other envs files are written (by eject-conf or import --conf)
   * @param {*} workspaceConfig
   */


  static load({
    componentDir,
    workspaceDir,
    configDir,
    workspaceConfig
  }) {
    return (0, _bluebird().coroutine)(function* () {
      if (!configDir) throw new TypeError('component-config.load configDir arg is empty');

      const bitJsonPath = _abstractConfig().default.composeBitJsonPath(configDir);

      const loadBitJson =
      /*#__PURE__*/
      function () {
        var _ref = (0, _bluebird().coroutine)(function* () {
          try {
            const file = yield _abstractConfig().default.loadJsonFileIfExist(bitJsonPath);
            return file;
          } catch (e) {
            throw new (_generalError().default)(`bit.json at "${bitJsonPath}" is not a valid JSON file, re-import the component with "--conf" flag to recreate it`);
          }
        });

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

      const loadPackageJson =
      /*#__PURE__*/
      function () {
        var _ref2 = (0, _bluebird().coroutine)(function* () {
          if (!componentDir) return null;

          try {
            const file = yield _packageJsonFile().default.load(workspaceDir, componentDir);
            if (!file.fileExist) return null;
            return file;
          } catch (e) {
            throw new (_generalError().default)(`package.json at ${_abstractConfig().default.composePackageJsonPath(componentDir)} is not a valid JSON file, consider to re-import the file to re-generate the file`);
          }
        });

        return function loadPackageJson() {
          return _ref2.apply(this, arguments);
        };
      }();

      const [bitJsonFile, packageJsonFile] = yield Promise.all([loadBitJson(), loadPackageJson()]);
      const bitJsonConfig = bitJsonFile || {};
      const packageJsonObject = packageJsonFile ? packageJsonFile.packageJsonObject : null;
      const packageJsonHasConfig = Boolean(packageJsonObject && packageJsonObject.bit);
      const packageJsonConfig = packageJsonHasConfig ? packageJsonObject.bit : {}; // in case of conflicts, bit.json wins package.json

      const config = Object.assign(packageJsonConfig, bitJsonConfig);
      const componentConfig = ComponentConfig.mergeWithWorkspaceConfig(config, workspaceConfig);
      componentConfig.path = bitJsonPath;
      componentConfig.componentHasWrittenConfig = packageJsonHasConfig || Boolean(bitJsonFile);
      componentConfig.packageJsonFile = packageJsonFile;
      return componentConfig;
    })();
  }

}

exports.default = ComponentConfig;