"use strict";

function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;
exports.string = string;
var _parser = _interopRequireWildcard(require("./parser.js"));
var _response = _interopRequireDefault(require("./response.js"));
var _tuple = require("../data/tuple.js");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
/*
 * Masala Parser
 * https://github.com/masala/masala-parser
 *
 * Copyright (c) 2016-2025 Didier Plaindoux & Nicolas Zozol
 * Licensed under the LGPL2 license.
 */

// (Stream 'c -> number -> Response 'a 'c) -> Parser 'a 'c
function parse(p) {
  return new _parser["default"](p);
}

// (('b -> Parser 'a 'c) * 'b)-> Parser 'a 'c
function lazy(p, parameters) {
  var self = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  if (parameters && !Array.isArray(parameters)) {
    throw 'Lazy(parser, [params]) function expect parser parameters to be packed into an array';
  }

  // equivalent of p(...parameters), but would fail if parameters are undefined
  // In some case, p is a function that require a 'this' bound to the function
  // https://github.com/d-plaindoux/masala-parser/issues/9
  return new _parser["default"](function (input) {
    var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    return p.apply(self, parameters).parse(input, index);
  });
}

// 'a -> Parser 'a 'c
function returns(v) {
  return new _parser["default"](function (input) {
    var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    return _response["default"].accept(v, input, index, false);
  });
}

// unit -> Parser 'a 'c
function error() {
  return new _parser["default"](function (input) {
    var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    // TODO: add an optional logger parameter, and log
    return _response["default"].reject(input, index, false);
  });
}

// ('a -> boolean) -> Parser a 'c
// index is forwarded at index +1
function satisfy(predicate) {
  return new _parser["default"](function (input) {
    var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    return input.get(index).filter(predicate).map(function (value) {
      return _response["default"].accept(value, input, index + 1, true);
    }).lazyRecoverWith(function () {
      return _response["default"].reject(input, index, false);
    });
  });
}

// Parser 'a 'c -> Parser 'a 'c
function doTry(p) {
  return new _parser["default"](function (input) {
    var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    return p.parse(input, index).fold(function (accept) {
      return accept;
    },
    // Compared to satisfy, we come back to initial offset
    function (reject) {
      return _response["default"].reject(input, reject.offset, false);
    });
  });
}
function layer(p) {
  return new _parser["default"](function (input) {
    var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    return p.parse(input, index).fold(function (accept) {
      // TODO logger

      return _response["default"].accept(new _tuple.Tuple().append(accept.value), input, index, false);
    },
    // Compared to satisfy, we come back to initial offset
    function (reject) {
      return reject;
    });
  });
}

// unit -> Parser 'a 'c
function any() {
  return satisfy(function () {
    return true;
  });
}

// unit -> Parser 'a 'c
function nop() {
  return new _parser["default"](function (input) {
    var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    return _response["default"].accept(_tuple.NEUTRAL, input, index, true);
  });
}

// Parser 'a ? -> Parser 'a 'a
function not(p) {
  return doTry(p).then(error()).or(any());
}

// int -> Parser (List 'a') a'
function subStream(length) {
  return any().occurrence(length);
}
function startWith(value) {
  return nop().returns(value);
}
function moveUntil(stop) {
  if (typeof stop === 'string') {
    return searchStringStart(stop);
  }
  if (Array.isArray(stop)) {
    return searchArrayStringStart(stop);
  }

  // TODO: change undefined by a Symbol
  // TODO: for better performance, maybe check in the map if the symbol is included, and remove the or
  var foundEos = Symbol('found-eos');
  return doTry(not(stop).rep().then((0, _parser.eos)()).returns(foundEos)).or(not(stop).rep().map(function (chars) {
    return chars.join('');
  })).filter(function (v) {
    return v !== foundEos;
  });
}
function dropTo(stop) {
  if (typeof stop === 'string') {
    return moveUntil(stop).then(string(stop)).drop();
  } else {
    return moveUntil(stop).then(stop).drop();
  }
}
var _default = exports["default"] = {
  parse: parse,
  nop: nop,
  "try": doTry,
  any: any,
  subStream: subStream,
  not: not,
  layer: layer,
  lazy: lazy,
  returns: returns,
  error: error,
  eos: _parser.eos,
  satisfy: satisfy,
  startWith: startWith,
  moveUntil: moveUntil,
  dropTo: dropTo
};
/**Optimization functions */
/**
 * Will work only if input.source is a String
 * @param string
 * @returns {Parser}
 */
function searchStringStart(string) {
  return new _parser["default"](function (input) {
    var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    if (typeof input.source !== 'string') {
      throw 'Input source must be a String';
    }
    var sourceIndex = input.source.indexOf(string, index);
    if (sourceIndex > 0) {
      return _response["default"].accept(input.source.substring(index, sourceIndex), input, sourceIndex, true);
    } else {
      return _response["default"].reject(input, index, false);
    }
  });
}

/**
 * Will work only if input.source is a String
 */
function searchArrayStringStart(array) {
  return new _parser["default"](function (input) {
    var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    if (typeof input.source !== 'string') {
      throw 'Input source must be a String';
    }
    var sourceIndex = -1;
    var i = 0;
    while (sourceIndex < 0 && i < array.length) {
      var needle = array[i];
      sourceIndex = input.source.indexOf(needle, index);
      i++;
      if (sourceIndex > 0) {
        break;
      }
    }

    //const sourceIndex = input.source.indexOf(string, index)

    if (sourceIndex > 0) {
      return _response["default"].accept(input.source.substring(index, sourceIndex), input, sourceIndex, true);
    } else {
      return _response["default"].reject(input, index, false);
    }
  });
}

// string -> Parser string char
// index is forwarded at the length of the string
function string(s) {
  return new _parser["default"](function (input) {
    var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    if (input.subStreamAt(s.split(''), index)) {
      return _response["default"].accept(s, input, index + s.length, true);
    } else {
      return _response["default"].reject(input, index, false);
    }
  });
}
//# sourceMappingURL=flow-bundle.js.map