// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

enum EscapeFlag {
  CaseInsensitive = 1,
  MatchAny = 2,
}

function escape(s: string, flags?: number): string {
  flags = flags === undefined ? 0 : flags;
  // See https://www.sqlite.org/lang_expr.html#:~:text=A%20string%20constant
  s = s.replaceAll("'", "''");
  s = s.replaceAll('[', '[[]');
  if (flags & EscapeFlag.CaseInsensitive) {
    s = s.replace(/[a-zA-Z]/g, (m) => {
      const lower = m.toLowerCase();
      const upper = m.toUpperCase();
      return `[${lower}${upper}]`;
    });
  }
  s = s.replaceAll('?', '[?]');
  s = s.replaceAll('*', '[*]');
  if (flags & EscapeFlag.MatchAny) {
    s = `*${s}*`;
  }
  s = `'${s}'`;
  return s;
}

export function escapeQuery(s: string): string {
  return escape(s);
}

export function escapeSearchQuery(s: string): string {
  return escape(s, EscapeFlag.CaseInsensitive | EscapeFlag.MatchAny);
}

export function escapeGlob(s: string): string {
  // For globs we are only preoccupied by mismatching single quotes.
  s = s.replaceAll("'", "''");
  return `'*${s}*'`;
}
