"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.MergeConflictFile = void 0;
function _constants() {
  const data = require("@teambit/legacy/dist/constants");
  _constants = function () {
    return data;
  };
  return data;
}
function _path() {
  const data = _interopRequireDefault(require("path"));
  _path = function () {
    return data;
  };
  return data;
}
function _fsExtra() {
  const data = _interopRequireDefault(require("fs-extra"));
  _fsExtra = function () {
    return data;
  };
  return data;
}
function _mergeConfigConflict() {
  const data = require("./exceptions/merge-config-conflict");
  _mergeConfigConflict = function () {
    return data;
  };
  return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const idPrefix = `[*]`;
const idDivider = '-'.repeat(80);
class MergeConflictFile {
  constructor(workspacePath) {
    this.workspacePath = workspacePath;
    _defineProperty(this, "conflictPerId", void 0);
  }
  addConflict(id, conflict) {
    if (!this.conflictPerId) this.conflictPerId = {};
    this.conflictPerId[id] = conflict;
  }
  removeConflict(id) {
    delete this.conflictPerId?.[id];
  }
  async getConflict(id) {
    await this.loadIfNeeded();
    if (!this.conflictPerId) throw new Error(`this.conflictPerId must be instantiated after load`);
    return this.conflictPerId[id];
  }
  getConflictAssumeIsLoaded(id) {
    if (!this.conflictPerId) throw new Error(`MergeConflictFile was not loaded yet, please load it before calling this function`);
    return this.conflictPerId[id];
  }
  getConflictParsed(id) {
    const configMergeContent = this.getConflictAssumeIsLoaded(id);
    if (!configMergeContent) return undefined;
    try {
      return JSON.parse(configMergeContent);
    } catch (err) {
      if (this.stringHasConflictMarker(configMergeContent)) {
        throw new (_mergeConfigConflict().MergeConfigConflict)(this.getPath());
      }
      throw new Error(`unable to parse the merge-conflict entry for ${id} as the JSON is invalid. err: ${err.message}`);
    }
  }
  hasConflict() {
    return Boolean(this.conflictPerId && Object.keys(this.conflictPerId).length);
  }
  getPath() {
    return _path().default.join(this.workspacePath, _constants().MergeConfigFilename);
  }
  async loadIfNeeded() {
    if (this.conflictPerId) return; // already loaded
    const fileContent = await this.getFileContentIfExists();
    if (!fileContent) {
      this.conflictPerId = {}; // to indicate that it's loaded
      return;
    }
    const parsedConflict = this.parseConflict(fileContent);
    this.conflictPerId = parsedConflict;
  }
  async write() {
    if (!this.hasConflict()) return;
    const afterFormat = this.formatConflicts();
    await _fsExtra().default.writeFile(this.getPath(), afterFormat);
  }
  async delete() {
    await _fsExtra().default.remove(this.getPath());
  }
  formatConflicts() {
    const conflictPerId = this.conflictPerId;
    if (!conflictPerId) throw new Error('conflictPerId is not populated');
    const title = `# Resolve configuration conflicts per component and make sure the Component ID remain in place`;
    const conflicts = Object.keys(conflictPerId).map(id => {
      const conflict = conflictPerId[id];
      return `${idDivider}
${idPrefix} ${id}
${idDivider}
${conflict}`;
    }).join('\n\n');
    return `${title}\n\n${conflicts}`;
  }
  stringHasConflictMarker(str) {
    return str.includes('<<<<<<<') || str.includes('>>>>>>>');
  }
  parseConflict(conflict) {
    // remove irrelevant lines
    conflict = conflict.split('\n').filter(line => line !== idDivider && !line.startsWith('#')).join('\n');
    // split by id
    const conflictPerId = {};
    const split = conflict.split(idPrefix);
    split.forEach(conflictItem => {
      const conflictItemSplit = conflictItem.split('\n');
      const [rawId, ...conflictStr] = conflictItemSplit;
      const id = rawId.trim();
      if (!id) return; // first line has it empty
      conflictPerId[id] = conflictStr.join('\n');
    });
    return conflictPerId;
  }
  async getFileContentIfExists() {
    const filePath = this.getPath();
    let fileContent;
    try {
      fileContent = await _fsExtra().default.readFile(filePath, 'utf-8');
    } catch (err) {
      if (err.code === 'ENOENT') {
        return undefined;
      }
      throw err;
    }
    return fileContent;
  }
}
exports.MergeConflictFile = MergeConflictFile;

//# sourceMappingURL=merge-conflict-file.js.map