"use strict";

var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
_Object$defineProperty(exports, "__esModule", {
  value: true
});
exports.default = formatText;
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/typeof"));
var _sprintfJs = require("sprintf-js");
// Copyright © 2020 Interplanetary Database Association e.V.,
// Planetmint and IPDB software contributors.
// SPDX-License-Identifier: (AGPL-3.0-or-later AND CC-BY-4.0)
// Code is AGPL-3.0-or-later and docs are CC-BY-4.0

// Regexes taken from or inspired by sprintf-js
var Regex = {
  TEMPLATE_LITERAL: /\${([^)]+?)}/g,
  KEY: /^([a-z_][a-z_\d]*)/i,
  KEY_ACCESS: /^\.([a-z_][a-z_\d]*)/i,
  INDEX_ACCESS: /^\[(\d+)\]/
};

/**
 * imported from https://github.com/bigchaindb/js-utility-belt/
 * @private
 * Formats strings similarly to C's sprintf, with the addition of '${...}' formats.
 *
 * Makes a first pass replacing '${...}' formats before passing the expanded string and other
 * arguments to sprintf-js. For more information on what sprintf can do, see
 * https://github.com/alexei/sprintf.js.
 *
 * Examples:
 *   formatText('Hi there ${dimi}!', { dimi: 'Dimi' })
 *       => 'Hi there Dimi!'
 *
 *   formatText('${database} is %(status)s', { database: 'Planetmint', status: 'fresh' })
 *       => 'Planetmint is fresh'
 *
 * Like sprintf-js, string interpolation for keywords and indexes is supported too:
 *   formatText('Berlin is best known for its ${berlin.topKnownFor[0].name}', {
 *       berlin: {
 *           topKnownFor: [{
 *               name: 'Currywurst'
 *           }, ...
 *           ]
 *       }
 *   })
 *       => 'Berlin is best known for its Currywurst'
 */
function formatText(s) {
  var _context;
  var expandedFormatStr = s;

  // Try to replace formats of the form '${...}' if named replacement fields are used
  for (var _len = arguments.length, argv = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    argv[_key - 1] = arguments[_key];
  }
  if (s && argv.length === 1 && (0, _typeof2.default)(argv[0]) === 'object') {
    var templateSpecObj = argv[0];
    expandedFormatStr = s.replace(Regex.TEMPLATE_LITERAL, function (match, replacement) {
      var interpolationLeft = replacement;

      /**
       * @private
       * Interpolation algorithm inspired by sprintf-js.
       *
       * Goes through the replacement string getting the left-most key or index to interpolate
       * on each pass. `value` at each step holds the last interpolation result, `curMatch` is
       * the current property match, and `interpolationLeft` is the portion of the replacement
       * string still to be interpolated.
       *
       * It's useful to note that RegExp.exec() returns with an array holding:
       *   [0]:  Full string matched
       *   [1+]: Matching groups
       *
       * And that in the regexes defined, the first matching group always corresponds to the
       * property matched.
       */
      var value;
      var curMatch = Regex.KEY.exec(interpolationLeft);
      if (curMatch !== null) {
        value = templateSpecObj[curMatch[1]];

        // Assigning in the conditionals here makes the code less bloated
        /* eslint-disable no-cond-assign */
        while ((interpolationLeft = interpolationLeft.substring(curMatch[0].length)) && value != null) {
          if (curMatch = Regex.KEY_ACCESS.exec(interpolationLeft)) {
            value = value[curMatch[1]];
          } else if (curMatch = Regex.INDEX_ACCESS.exec(interpolationLeft)) {
            value = value[curMatch[1]];
          } else {
            break;
          }
        }
        /* eslint-enable no-cond-assign */
      }

      // If there's anything left to interpolate by the end then we've failed to interpolate
      // the entire replacement string.
      if (interpolationLeft.length) {
        throw new SyntaxError("[formatText] failed to parse named argument key: ".concat(replacement));
      }
      return value;
    });
  }
  return _sprintfJs.sprintf.apply(void 0, (0, _concat.default)(_context = [expandedFormatStr]).call(_context, argv));
}
//# sourceMappingURL=format_text.js.map