"use strict";

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

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 _path() {
  const data = _interopRequireDefault(require("path"));

  _path = function () {
    return data;
  };

  return data;
}

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

  _ramda = function () {
    return data;
  };

  return data;
}

function RA() {
  const data = _interopRequireWildcard(require("ramda-adjunct"));

  RA = function () {
    return data;
  };

  return data;
}

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

  _fsExtra = function () {
    return data;
  };

  return data;
}

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

  _bitId = function () {
    return data;
  };

  return data;
}

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

  _utils = 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;
}

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

  _jsonFile = function () {
    return data;
  };

  return data;
}

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

  _packageJsonFile = function () {
    return data;
  };

  return data;
}

function _dataToPersist() {
  const data = _interopRequireDefault(require("../component/sources/data-to-persist"));

  _dataToPersist = function () {
    return data;
  };

  return data;
}

/**
 * There are two Bit Config: WorkspaceConfig and ComponentConfig, both inherit this class.
 * The config data can be written in package.json inside "bit" property. And, can be written in
 * bit.json file. Also, it might be written in both, in which case, if there is any conflict, the
 * bit.json wins.
 */
class AbstractConfig {
  constructor(props) {
    (0, _defineProperty2().default)(this, "writeToPackageJson", false);
    (0, _defineProperty2().default)(this, "writeToBitJson", false);
    this._compiler = props.compiler || {};
    this._tester = props.tester || {};
    this.lang = props.lang || _constants().DEFAULT_LANGUAGE;
    this.bindingPrefix = props.bindingPrefix || _constants().DEFAULT_BINDINGS_PREFIX;
    this.extensions = props.extensions || _constants().DEFAULT_EXTENSIONS;
  }

  get compiler() {
    const compilerObj = AbstractConfig.transformEnvToObject(this._compiler);
    if (_ramda().default.isEmpty(compilerObj)) return undefined;
    return compilerObj;
  }

  set compiler(compiler) {
    this._compiler = AbstractConfig.transformEnvToObject(compiler);
  }

  get tester() {
    const testerObj = AbstractConfig.transformEnvToObject(this._tester);
    if (_ramda().default.isEmpty(testerObj)) return undefined;
    return testerObj;
  }

  set tester(tester) {
    this._tester = AbstractConfig.transformEnvToObject(tester);
  }

  addDependencies(bitIds) {
    const idObjects = _ramda().default.mergeAll(bitIds.map(bitId => bitId.toObject()));

    this.dependencies = _ramda().default.merge(this.dependencies, idObjects);
    return this;
  }

  addDependency(bitId) {
    this.dependencies = _ramda().default.merge(this.dependencies, bitId.toObject());
    return this;
  }

  hasCompiler() {
    return !!this.compiler && this._compiler !== _constants().NO_PLUGIN_TYPE && !_ramda().default.isEmpty(this.compiler);
  }

  hasTester() {
    return !!this.tester && this._tester !== _constants().NO_PLUGIN_TYPE && !_ramda().default.isEmpty(this.tester);
  }

  getEnvsByType(type) {
    if (type === _constants().COMPILER_ENV_TYPE) {
      return this.compiler;
    }

    return this.tester;
  }
  /**
   * if there is only one env (compiler/tester) and it doesn't have any special configuration, only
   * the name, convert it to a string.
   */


  static convertEnvToStringIfPossible(envObj) {
    if (!envObj) return undefined;
    if (Object.keys(envObj).length !== 1) return envObj; // it has more than one id

    const envId = Object.keys(envObj)[0];

    if (RA().isNilOrEmpty(envObj[envId].rawConfig) && RA().isNilOrEmpty(envObj[envId].options) && RA().isNilOrEmpty(envObj[envId].files)) {
      return envId;
    }

    return envObj;
  }

  getDependencies() {
    return _bitId().BitIds.fromObject(this.dependencies);
  }

  toPlainObject() {
    const isPropDefaultOrNull = (val, key) => {
      if (!val) return false;
      if (key === 'lang') return val !== _constants().DEFAULT_LANGUAGE;
      if (key === 'bindingPrefix') return val !== _constants().DEFAULT_BINDINGS_PREFIX;
      if (key === 'extensions') return !_ramda().default.equals(val, _constants().DEFAULT_EXTENSIONS);
      return true;
    };

    return (0, _utils().filterObject)({
      lang: this.lang,
      bindingPrefix: this.bindingPrefix,
      env: {
        compiler: AbstractConfig.convertEnvToStringIfPossible(this.compiler),
        tester: AbstractConfig.convertEnvToStringIfPossible(this.tester)
      },
      dependencies: this.dependencies,
      extensions: this.extensions
    }, isPropDefaultOrNull);
  }

  write({
    workspaceDir,
    componentDir
  }) {
    var _this = this;

    return (0, _bluebird().coroutine)(function* () {
      const jsonFiles = yield _this.prepareToWrite({
        workspaceDir,
        componentDir
      });
      const dataToPersist = new (_dataToPersist().default)();
      dataToPersist.addManyFiles(jsonFiles);
      dataToPersist.addBasePath(workspaceDir);
      return dataToPersist.persistAllToFS();
    })();
  }

  prepareToWrite({
    workspaceDir,
    componentDir = '.'
  }) {
    var _this2 = this;

    return (0, _bluebird().coroutine)(function* () {
      const plainObject = _this2.toPlainObject();

      const JsonFiles = [];

      if (_this2.writeToPackageJson) {
        const packageJsonFile = yield _packageJsonFile().default.load(workspaceDir, componentDir);
        packageJsonFile.addOrUpdateProperty('bit', plainObject);
        JsonFiles.push(packageJsonFile.toVinylFile());
      }

      if (_this2.writeToBitJson) {
        const bitJsonPath = AbstractConfig.composeBitJsonPath(componentDir);
        const params = {
          base: componentDir,
          override: true,
          path: bitJsonPath,
          content: plainObject
        };
        JsonFiles.push(_jsonFile().default.load(params));
      }

      return JsonFiles;
    })();
  }

  static composeBitJsonPath(bitPath) {
    return _path().default.join(bitPath, _constants().BIT_JSON);
  }

  static composePackageJsonPath(bitPath) {
    return _path().default.join(bitPath, _constants().PACKAGE_JSON);
  }

  static pathHasBitJson(bitPath) {
    var _this3 = this;

    return (0, _bluebird().coroutine)(function* () {
      return _fsExtra().default.exists(_this3.composeBitJsonPath(bitPath));
    })();
  }

  static pathHasPackageJson(bitPath) {
    var _this4 = this;

    return (0, _bluebird().coroutine)(function* () {
      return _fsExtra().default.exists(_this4.composePackageJsonPath(bitPath));
    })();
  }

  static loadJsonFileIfExist(jsonFilePath) {
    return (0, _bluebird().coroutine)(function* () {
      try {
        const file = yield _fsExtra().default.readJson(jsonFilePath);
        return file;
      } catch (e) {
        if (e.code === 'ENOENT') return null;
        throw e;
      }
    })();
  }

  static removeIfExist(bitPath) {
    var _this5 = this;

    return (0, _bluebird().coroutine)(function* () {
      const dirToRemove = _this5.composeBitJsonPath(bitPath);

      if (_fsExtra().default.exists(dirToRemove)) {
        _logger().default.info(`abstract-config, deleting ${dirToRemove}`);

        return _fsExtra().default.remove(dirToRemove);
      }

      return false;
    })();
  }

  static transformEnvToObject(env) {
    if (typeof env === 'string') {
      if (env === _constants().NO_PLUGIN_TYPE) return {};
      return {
        [env]: {}
      };
    }

    return env;
  }

}

exports.default = AbstractConfig;