import { RegExpParser } from "../@chevrotain/regexp-to-ast/lib-src-regexp-parser.js";
import { BaseRegExpVisitor } from "../@chevrotain/regexp-to-ast/lib-src-base-regexp-visitor.js";
const NEWLINE_REGEXP = /\r?\n/gm;
const regexpParser = new RegExpParser();
class TerminalRegExpVisitor extends BaseRegExpVisitor {
  constructor() {
    super(...arguments);
    this.isStarting = true;
    this.endRegexpStack = [];
    this.multiline = false;
  }
  get endRegex() {
    return this.endRegexpStack.join("");
  }
  reset(regex) {
    this.multiline = false;
    this.regex = regex;
    this.startRegexp = "";
    this.isStarting = true;
    this.endRegexpStack = [];
  }
  visitGroup(node) {
    if (node.quantifier) {
      this.isStarting = false;
      this.endRegexpStack = [];
    }
  }
  visitCharacter(node) {
    const char = String.fromCharCode(node.value);
    if (!this.multiline && char === "\n") {
      this.multiline = true;
    }
    if (node.quantifier) {
      this.isStarting = false;
      this.endRegexpStack = [];
    } else {
      const escapedChar = escapeRegExp(char);
      this.endRegexpStack.push(escapedChar);
      if (this.isStarting) {
        this.startRegexp += escapedChar;
      }
    }
  }
  visitSet(node) {
    if (!this.multiline) {
      const set = this.regex.substring(node.loc.begin, node.loc.end);
      const regex = new RegExp(set);
      this.multiline = Boolean("\n".match(regex));
    }
    if (node.quantifier) {
      this.isStarting = false;
      this.endRegexpStack = [];
    } else {
      const set = this.regex.substring(node.loc.begin, node.loc.end);
      this.endRegexpStack.push(set);
      if (this.isStarting) {
        this.startRegexp += set;
      }
    }
  }
  visitChildren(node) {
    if (node.type === "Group") {
      const group = node;
      if (group.quantifier) {
        return;
      }
    }
    super.visitChildren(node);
  }
}
const visitor = new TerminalRegExpVisitor();
function isMultilineComment(regexp) {
  try {
    if (typeof regexp === "string") {
      regexp = new RegExp(regexp);
    }
    regexp = regexp.toString();
    visitor.reset(regexp);
    visitor.visit(regexpParser.pattern(regexp));
    return visitor.multiline;
  } catch (_a) {
    return false;
  }
}
const whitespaceCharacters = "\f\n\r	\v              \u2028\u2029  　\uFEFF".split("");
function isWhitespace(value) {
  const regexp = typeof value === "string" ? new RegExp(value) : value;
  return whitespaceCharacters.some((ws) => regexp.test(ws));
}
function escapeRegExp(value) {
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function getCaseInsensitivePattern(keyword) {
  return Array.prototype.map.call(keyword, (letter) => /\w/.test(letter) ? `[${letter.toLowerCase()}${letter.toUpperCase()}]` : escapeRegExp(letter)).join("");
}
function partialMatches(regex, input) {
  const partial = partialRegExp(regex);
  const match = input.match(partial);
  return !!match && match[0].length > 0;
}
function partialRegExp(regex) {
  if (typeof regex === "string") {
    regex = new RegExp(regex);
  }
  const re = regex, source = regex.source;
  let i = 0;
  function process() {
    let result = "", tmp;
    function appendRaw(nbChars) {
      result += source.substr(i, nbChars);
      i += nbChars;
    }
    function appendOptional(nbChars) {
      result += "(?:" + source.substr(i, nbChars) + "|$)";
      i += nbChars;
    }
    while (i < source.length) {
      switch (source[i]) {
        case "\\":
          switch (source[i + 1]) {
            case "c":
              appendOptional(3);
              break;
            case "x":
              appendOptional(4);
              break;
            case "u":
              if (re.unicode) {
                if (source[i + 2] === "{") {
                  appendOptional(source.indexOf("}", i) - i + 1);
                } else {
                  appendOptional(6);
                }
              } else {
                appendOptional(2);
              }
              break;
            case "p":
            case "P":
              if (re.unicode) {
                appendOptional(source.indexOf("}", i) - i + 1);
              } else {
                appendOptional(2);
              }
              break;
            case "k":
              appendOptional(source.indexOf(">", i) - i + 1);
              break;
            default:
              appendOptional(2);
              break;
          }
          break;
        case "[":
          tmp = /\[(?:\\.|.)*?\]/g;
          tmp.lastIndex = i;
          tmp = tmp.exec(source) || [];
          appendOptional(tmp[0].length);
          break;
        case "|":
        case "^":
        case "$":
        case "*":
        case "+":
        case "?":
          appendRaw(1);
          break;
        case "{":
          tmp = /\{\d+,?\d*\}/g;
          tmp.lastIndex = i;
          tmp = tmp.exec(source);
          if (tmp) {
            appendRaw(tmp[0].length);
          } else {
            appendOptional(1);
          }
          break;
        case "(":
          if (source[i + 1] === "?") {
            switch (source[i + 2]) {
              case ":":
                result += "(?:";
                i += 3;
                result += process() + "|$)";
                break;
              case "=":
                result += "(?=";
                i += 3;
                result += process() + ")";
                break;
              case "!":
                tmp = i;
                i += 3;
                process();
                result += source.substr(tmp, i - tmp);
                break;
              case "<":
                switch (source[i + 3]) {
                  case "=":
                  case "!":
                    tmp = i;
                    i += 4;
                    process();
                    result += source.substr(tmp, i - tmp);
                    break;
                  default:
                    appendRaw(source.indexOf(">", i) - i + 1);
                    result += process() + "|$)";
                    break;
                }
                break;
            }
          } else {
            appendRaw(1);
            result += process() + "|$)";
          }
          break;
        case ")":
          ++i;
          return result;
        default:
          appendOptional(1);
          break;
      }
    }
    return result;
  }
  return new RegExp(process(), regex.flags);
}
export {
  NEWLINE_REGEXP,
  escapeRegExp,
  getCaseInsensitivePattern,
  isMultilineComment,
  isWhitespace,
  partialMatches,
  partialRegExp,
  whitespaceCharacters
};
//# sourceMappingURL=lib-utils-regexp-utils.js.map
