/*
 * Copyright 2019 WebAssembly Community Group participants
 *
 * 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.
 */

//
// String helpers.
//

#ifndef wasm_support_string_h
#define wasm_support_string_h

#include "support/utilities.h"
#include <algorithm>
#include <cctype>
#include <ostream>
#include <string>
#include <vector>

namespace wasm::String {

// Creates a vector of the split parts of a string, by a delimiter.
class Split : public std::vector<std::string> {
private:
  // If we split on newlines then we do not need to handle bracketing at all.
  // Otherwise, splitting on say "," does require us to understanding the
  // scoping of brackets, e.g., "foo(x, y),bar" should be split as "foo(x, y)",
  // "bar".
  bool needToHandleBracketingOperations = true;

  void split(const std::string& input, const std::string& delim);
  friend Split handleBracketingOperators(Split split);

public:
  // This can be used when we want to split on newlines if there are any, and if
  // there are not, then using the given delimiter.
  struct NewLineOr {
    const std::string delim;
    explicit NewLineOr(const std::string& delim) : delim(delim) {}
  };

  Split() = default;

  Split(const std::string& input, const NewLineOr& newLineOrDelim);
  Split(const std::string& input, const std::string& delim) {
    split(input, delim);
  }
};

template<typename StringLike,
         typename = std::enable_if_t<
           std::is_convertible_v<StringLike, std::string_view>>>
std::string join(const std::vector<StringLike>& strs, std::string_view sep) {
  if (strs.empty()) {
    return "";
  }

  std::string ret = std::string(strs[0]);
  for (size_t i = 1; i < strs.size(); i++) {
    ret.append(sep);
    ret.append(strs[i]);
  }

  return ret;
}

// Handles bracketing in a list initially split by ",", but the list may
// contain nested ","s. For example,
//   void foo(int, double)
// must be kept together because of the "(". Likewise, "{", "<", "[" are
// handled.
Split handleBracketingOperators(Split split);

// Does a simple '*' wildcard match between a pattern and a value.
bool wildcardMatch(const std::string& pattern, const std::string& value);

// Removes any extra whitespace or \0.
std::string trim(const std::string& input);

inline bool isNumber(const std::string& str) {
  return !str.empty() && std::all_of(str.begin(), str.end(), ::isdigit);
}

std::ostream& printEscaped(std::ostream& os, std::string_view str);

// `str` must be a valid WTF-16 string.
std::ostream& printEscapedJSON(std::ostream& os, std::string_view str);

std::ostream& writeWTF8CodePoint(std::ostream& os, uint32_t u);

std::ostream& writeWTF16CodePoint(std::ostream& os, uint32_t u);

// Writes the WTF-16LE encoding of the given WTF-8 string to `os`, inserting
// replacement characters as necessary when encountering invalid WTF-8. Returns
// `true` iff the input was valid WTF-8.
bool convertWTF8ToWTF16(std::ostream& os, std::string_view str);

// Writes the WTF-8 encoding of the given WTF-16LE string to `os`, inserting a
// replacement character at the end if the string is an odd number of bytes.
// Returns `true` iff the input was valid WTF-16.
bool convertWTF16ToWTF8(std::ostream& os, std::string_view str);

// Writes the UTF-8 encoding of the given UTF-16LE string to `os`, inserting a
// replacement character in place of any unpaired surrogate or incomplete code
// unit. Returns `true` if the input was valid UTF-16.
bool convertUTF16ToUTF8(std::ostream& os, std::string_view str);

// Whether the string is valid UTF-8.
bool isUTF8(std::string_view str);

// Given a string of properly-escaped JSON in UTF8, unescape it into WTF16.
std::ostream& unescapeUTF8JSONtoWTF16(std::ostream& os, const char* str);

} // namespace wasm::String

#endif // wasm_support_string_h
