"use strict";

exports.__esModule = true;
exports.formatFlowSingleQuoted = exports.formatFlowPlain = exports.formatFlowDoubleQuoted = exports.formatBlockLiteral = exports.formatBlockFolded = void 0;
var _ramda = require("ramda");
var _ramdaAdjunct = require("ramda-adjunct");
var _unraw = require("unraw");
/**
 * Helpers.
 */

const blockStyleRegExp = /^(?<style>[|>])(?<chomping>[+-]?)(?<indentation>[0-9]*)\s/;
const getIndentationIndicator = content => {
  const matches = content.match(blockStyleRegExp);
  const indicator = (0, _ramda.pathOr)('', ['groups', 'indentation'], matches);
  return (0, _ramdaAdjunct.isEmptyString)(indicator) ? undefined : parseInt(indicator, 10);
};
const getIndentation = content => {
  const explicitIndentationIndicator = getIndentationIndicator(content);

  // we have explicit indentation indicator
  if ((0, _ramdaAdjunct.isInteger)(explicitIndentationIndicator)) {
    return (0, _ramdaAdjunct.repeatStr)(' ', explicitIndentationIndicator);
  }

  // we assume indentation indicator from first line
  const firstLine = (0, _ramda.pathOr)('', [1], content.split('\n'));
  const implicitIndentationIndicator = (0, _ramda.pathOr)(0, ['groups', 'indentation', 'length'], firstLine.match(/^(?<indentation>[ ]*)/));
  return (0, _ramdaAdjunct.repeatStr)(' ', implicitIndentationIndicator);
};
const getChompingIndicator = content => {
  const matches = content.match(blockStyleRegExp);
  const indicator = (0, _ramda.pathOr)('', ['groups', 'chomping'], matches);
  return (0, _ramdaAdjunct.isEmptyString)(indicator) ? undefined : indicator;
};
const chomp = (indicator, content) => {
  // clip (single newline at end)
  if ((0, _ramdaAdjunct.isUndefined)(indicator)) {
    return `${(0, _ramdaAdjunct.trimEnd)(content)}\n`;
  }
  // strip (no newline at end)
  if (indicator === '-') {
    return (0, _ramdaAdjunct.trimEnd)(content);
  }
  // keep (all newlines from end)
  if (indicator === '+') {
    return content;
  }
  return content;
};

/**
 * Normalizes lines breaks.
 * https://yaml.org/spec/1.2/spec.html#line%20break/normalization/
 */
// @ts-ignore
const normalizeLineBreaks = val => val.replace(/\r\n/g, '\n');

// prevent escaped line breaks from being converted to a space
const preventLineBreakCollapseToSpace = val => val.replace(/\\\n\s*/g, '');

// collapse line breaks into spaces
const collapseLineBreakToSpace = val => {
  /**
   * Safari doesn't support negative lookbehind, thus we use mimicking technique:
   *
   * - https://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript
   *
   * Ideally we want to use following replace, but that's not currently possible:
   *
   * .replace(/[^\n]\n([^\n]+)/g, (match: string, p1: string) => ` ${p1.trimLeft()}`)
   */
  return val.replace(/(\n)?\n([^\n]+)/g, (match, p1, p2) => p1 ? match : ` ${p2.trimStart()}`).replace(/[\n]{2}/g, '\n');
};
const removeQuotes = (0, _ramda.curry)((quoteType, val) => val.replace(new RegExp(`^${quoteType}`), '').replace(new RegExp(`${quoteType}$`), ''));

/**
 * Formats Flow Scalar Plain style.
 * https://yaml.org/spec/1.2/spec.html#id2788859
 */
const formatFlowPlain = exports.formatFlowPlain = (0, _ramda.pipe)(normalizeLineBreaks, _ramda.trim, collapseLineBreakToSpace, (0, _ramda.split)('\n'), (0, _ramda.map)(_ramdaAdjunct.trimStart), (0, _ramda.join)('\n'));

/**
 * Formats Flow Scalar Single-Quoted style.
 * https://yaml.org/spec/1.2/spec.html#id2788097
 */

const formatFlowSingleQuoted = exports.formatFlowSingleQuoted = (0, _ramda.pipe)(normalizeLineBreaks, _ramda.trim, collapseLineBreakToSpace, (0, _ramda.split)('\n'), (0, _ramda.map)(_ramdaAdjunct.trimStart), (0, _ramda.join)('\n'), removeQuotes("'"));

/**
 * Formats Flow Scalar Double-Quoted style.
 * https://yaml.org/spec/1.2/spec.html#id2787109
 */
const formatFlowDoubleQuoted = exports.formatFlowDoubleQuoted = (0, _ramda.pipe)(normalizeLineBreaks, _ramda.trim, preventLineBreakCollapseToSpace, collapseLineBreakToSpace, _unraw.unraw, (0, _ramda.split)('\n'), (0, _ramda.map)(_ramdaAdjunct.trimStart), (0, _ramda.join)('\n'), removeQuotes('"'));

/**
 * Formats Block Scalar Literal style.
 * https://yaml.org/spec/1.2/spec.html#id2795688
 */
const formatBlockLiteral = content => {
  const indentation = getIndentation(content);
  const chompingIndicator = getChompingIndicator(content);
  const normalized = normalizeLineBreaks(content);
  const lines = (0, _ramda.tail)(normalized.split('\n')); // first line only contains indicators
  const transducer = (0, _ramda.compose)((0, _ramda.map)((0, _ramdaAdjunct.trimCharsStart)(indentation)), (0, _ramda.map)((0, _ramdaAdjunct.concatRight)('\n')));
  // @ts-ignore
  const deindented = (0, _ramda.transduce)(transducer, _ramda.concat, '', lines);
  return chomp(chompingIndicator, deindented);
};

/**
 * Formats BLock Scalar Folded style.
 * https://yaml.org/spec/1.2/spec.html#id2796251
 */
exports.formatBlockLiteral = formatBlockLiteral;
const formatBlockFolded = content => {
  const indentation = getIndentation(content);
  const chompingIndicator = getChompingIndicator(content);
  const normalized = normalizeLineBreaks(content);
  const lines = (0, _ramda.tail)(normalized.split('\n')); // first line only contains indicators
  const transducer = (0, _ramda.compose)((0, _ramda.map)((0, _ramdaAdjunct.trimCharsStart)(indentation)), (0, _ramda.map)((0, _ramdaAdjunct.concatRight)('\n')));
  // @ts-ignore
  const deindented = (0, _ramda.transduce)(transducer, _ramda.concat, '', lines);
  const collapsed = collapseLineBreakToSpace(deindented);
  return chomp(chompingIndicator, collapsed);
};
exports.formatBlockFolded = formatBlockFolded;