"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ComponentConfigFile = void 0;
function _component() {
  const data = require("@teambit/component");
  _component = function () {
    return data;
  };
  return data;
}
function _constants() {
  const data = require("@teambit/legacy/dist/constants");
  _constants = function () {
    return data;
  };
  return data;
}
function _extensionData() {
  const data = require("@teambit/legacy/dist/consumer/config/extension-data");
  _extensionData = function () {
    return data;
  };
  return data;
}
function _component2() {
  const data = require("@teambit/component.sources");
  _component2 = function () {
    return data;
  };
  return data;
}
function _detectIndent() {
  const data = _interopRequireDefault(require("detect-indent"));
  _detectIndent = function () {
    return data;
  };
  return data;
}
function _detectNewline() {
  const data = _interopRequireDefault(require("detect-newline"));
  _detectNewline = 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 _config() {
  const data = require("@teambit/legacy/dist/consumer/config");
  _config = function () {
    return data;
  };
  return data;
}
function _lodash() {
  const data = require("lodash");
  _lodash = function () {
    return data;
  };
  return data;
}
function _exceptions() {
  const data = require("./exceptions");
  _exceptions = function () {
    return data;
  };
  return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const DEFAULT_INDENT = '  ';
const DEFAULT_NEWLINE = '\n';
class ComponentConfigFile {
  constructor(componentId, aspects, componentDir, propagate = false, options = {
    indent: DEFAULT_INDENT,
    newLine: DEFAULT_NEWLINE
  }, defaultScope) {
    this.componentId = componentId;
    this.aspects = aspects;
    this.componentDir = componentDir;
    this.propagate = propagate;
    this.options = options;
    this.defaultScope = defaultScope;
  }
  static async load(componentDir, aspectListFactory, outsideDefaultScope) {
    const filePath = ComponentConfigFile.composePath(componentDir);
    const isExist = await _fsExtra().default.pathExists(filePath);
    if (!isExist) {
      return undefined;
    }
    const content = await _fsExtra().default.readFile(filePath, 'utf-8');
    const parsed = parseComponentJsonContent(content, componentDir);
    const indent = (0, _detectIndent().default)(content).indent;
    const newLine = (0, _detectNewline().default)(content);
    const componentId = _component().ComponentID.fromObject(parsed.componentId, parsed.defaultScope || outsideDefaultScope);
    const aspects = await aspectListFactory(_extensionData().ExtensionDataList.fromConfigObject(parsed.extensions));
    return new ComponentConfigFile(componentId, aspects, componentDir, Boolean(parsed.propagate), {
      indent,
      newLine
    }, parsed.defaultScope);
  }
  static composePath(componentRootFolder) {
    return _path().default.join(componentRootFolder, _constants().COMPONENT_CONFIG_FILE_NAME);
  }
  async toVinylFile(options = {}) {
    const json = this.toJson();
    const filePath = ComponentConfigFile.composePath(this.componentDir);
    const isExist = await _fsExtra().default.pathExists(filePath);
    if (isExist && !options.override) {
      throw new (_exceptions().AlreadyExistsError)(filePath);
    }
    return _component2().JsonVinyl.load({
      base: _path().default.dirname(filePath),
      path: filePath,
      content: json,
      override: true,
      indent: this.options.indent,
      newline: this.options.newLine
    });
  }
  async write(options = {}) {
    const vinyl = await this.toVinylFile(options);
    await vinyl.write();
  }
  async addAspect(aspectId, config, resolveComponentId, shouldMergeConfig = false) {
    const existing = this.aspects.get(aspectId);
    if (existing) {
      const getNewConfig = () => {
        if (!shouldMergeConfig) return config;
        if (!config || config === '-') return config;
        if (!existing.config) return config;
        // @ts-ignore
        if (existing.config === '-') return config;
        return (0, _lodash().merge)(existing.config, config);
      };
      existing.config = getNewConfig();
    } else {
      const aspectEntry = await this.aspectEntryFromConfigObject(aspectId, config, resolveComponentId);
      this.aspects.entries.push(aspectEntry);
    }
  }
  async removeAspect(aspectId, markWithMinusIfNotExist, resolveComponentId) {
    const existing = this.aspects.get(aspectId);
    if (existing) {
      const aspectList = this.aspects.withoutEntries([aspectId]);
      this.aspects = aspectList;
    } else if (markWithMinusIfNotExist) {
      await this.addAspect(aspectId, _config().REMOVE_EXTENSION_SPECIAL_SIGN, resolveComponentId);
    }
  }
  async aspectEntryFromConfigObject(id, config, resolveComponentId) {
    const aspectId = await resolveComponentId(id);
    const legacyEntry = (0, _extensionData().configEntryToDataEntry)(id, config);
    return new (_component().AspectEntry)(aspectId, legacyEntry);
  }
  toJson() {
    return {
      componentId: this.componentId.toObject(),
      propagate: this.propagate,
      defaultScope: this.defaultScope,
      extensions: this.aspects.toConfigObject()
    };
  }
}
exports.ComponentConfigFile = ComponentConfigFile;
function parseComponentJsonContent(str, dir) {
  try {
    return JSON.parse(str);
  } catch (err) {
    throw new Error(`failed parsing component.json file at ${dir}. original error: ${err.message}`);
  }
}

//# sourceMappingURL=component-config-file.js.map