"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.dangerousNameRegex = void 0;
exports.enquoteDangerousNames = enquoteDangerousNames;
var _get = _interopRequireDefault(require("lodash/get"));
var _uniq = _interopRequireDefault(require("lodash/uniq"));
var _codeEditor = require("../code-editor");
require("codemirror/addon/hint/javascript-hint");
require("codemirror/addon/hint/sql-hint");
require("codemirror/addon/hint/anyword-hint");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// eslint-disable-next-line you-dont-need-lodash-underscore/get

const InjectCombinedHint = (CodeMirror, mode, customList, enquoteDangerousHintNames, quoteChar) => CodeMirror.registerHelper('hint', 'combined', (editor, options) => {
  const modeKey = mode === _codeEditor.CODE_EDITOR_MODES.SQL ? 'sql' : mode ?? 'anyword';
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  const modeHint = CodeMirror.hint[modeKey](editor, options);
  const anyhint = CodeMirror.hint.anyword(editor, options);
  const customListFiltered = matchCustomList(customList || [], editor, enquoteDangerousHintNames, quoteChar);
  let to;
  let from;
  if (modeHint.list.length > 0) {
    to = modeHint.to;
    from = modeHint.from;
  } else {
    // The codemirror types seems to be incorrect
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    to = anyhint.to;
    // The codemirror types seems to be incorrect
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    from = anyhint.from;
  }

  // Do not return a list of hints if the replaceable string has no length
  // prevents suggestions from being shown immediately after complete strings.
  if (!to || !from || to.ch === from.ch && to.line === from.line && customList?.length === 0) {
    return;
  }
  return {
    list: (0, _uniq.default)([...(0, _get.default)(modeHint, 'list', []), ...(customListFiltered || [])]),
    from,
    to
  };
});
function matchCustomList(list, editor, enquoteDangerousHintNames, quoteChar) {
  const WORD = /[\w$]+/;
  const cursor = editor.getCursor();
  const currentLine = editor.getLine(cursor.line); // Current row

  let start = cursor.ch;
  let end = start;
  while (end < currentLine.length && WORD.test(currentLine.charAt(end))) {
    ++end;
  }
  while (start && WORD.test(currentLine.charAt(start - 1))) {
    --start;
  }
  const currentWord = start !== end && currentLine.slice(start, end);
  const regex = new RegExp(`^${currentWord}`, 'i'); // regex for matches in custom list
  const resultList = !currentWord ? list : list.filter(item => item.match(regex)).sort();
  return enquoteDangerousHintNames ? enquoteDangerousNames(resultList, quoteChar) : resultList;
}
const dangerousNameRegex = exports.dangerousNameRegex = /[^\x00-\x7F]|[!@#$%^&*(),.?":{}|<> ]/gi;
function enquoteDangerousNames(list, quoteChar) {
  return list && list.map(name => dangerousNameRegex.test(name) ? `${quoteChar}${name}${quoteChar}` : name);
}
var _default = exports.default = InjectCombinedHint;