// Copyright 2022 The Chromium Authors
//
// 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
//
//     https://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.

#include "string_util.h"

#include <algorithm>
#include <string>

#include <openssl/base64.h>
#include <openssl/mem.h>

BSSL_NAMESPACE_BEGIN
namespace string_util {

bool IsAscii(std::string_view str) {
  for (unsigned char c : str) {
    if (c > 127) {
      return false;
    }
  }
  return true;
}

bool IsEqualNoCase(std::string_view str1, std::string_view str2) {
  return std::equal(str1.begin(), str1.end(), str2.begin(), str2.end(),
                    [](const unsigned char a, const unsigned char b) {
                      return OPENSSL_tolower(a) == OPENSSL_tolower(b);
                    });
}

bool EndsWithNoCase(std::string_view str, std::string_view suffix) {
  return suffix.size() <= str.size() &&
         IsEqualNoCase(suffix, str.substr(str.size() - suffix.size()));
}

bool StartsWithNoCase(std::string_view str, std::string_view prefix) {
  return prefix.size() <= str.size() &&
         IsEqualNoCase(prefix, str.substr(0, prefix.size()));
}

std::string FindAndReplace(std::string_view str, std::string_view find,
                           std::string_view replace) {
  std::string ret;

  if (find.empty()) {
    return std::string(str);
  }
  while (!str.empty()) {
    size_t index = str.find(find);
    if (index == std::string_view::npos) {
      ret.append(str);
      break;
    }
    ret.append(str.substr(0, index));
    ret.append(replace);
    str = str.substr(index + find.size());
  }
  return ret;
}

// TODO(bbe) get rid of this once we can c++20.
bool EndsWith(std::string_view str, std::string_view suffix) {
  return suffix.size() <= str.size() &&
         suffix == str.substr(str.size() - suffix.size());
}

// TODO(bbe) get rid of this once we can c++20.
bool StartsWith(std::string_view str, std::string_view prefix) {
  return prefix.size() <= str.size() && prefix == str.substr(0, prefix.size());
}

std::string HexEncode(Span<const uint8_t> data) {
  std::string ret;
  ret.reserve(data.size() * 2);
  for (uint8_t b : data) {
    static const char kHex[] = "0123456789ABCDEF";
    ret.push_back(kHex[b >> 4]);
    ret.push_back(kHex[b & 0xf]);
  }
  return ret;
}

std::vector<std::string_view> SplitString(std::string_view str,
                                          char split_char) {
  std::vector<std::string_view> out;

  if (str.empty()) {
    return out;
  }

  while (true) {
    // Find end of current token
    size_t i = str.find(split_char);

    // Add current token
    out.push_back(str.substr(0, i));

    if (i == str.npos) {
      // That was the last token
      break;
    }
    // Continue to next
    str = str.substr(i + 1);
  }

  return out;
}

bool Base64Encode(const std::string_view &input, std::string *output) {
  size_t len;
  if (!EVP_EncodedLength(&len, input.size())) {
    return false;
  }
  std::vector<char> encoded(len);
  len = EVP_EncodeBlock(reinterpret_cast<uint8_t *>(encoded.data()),
                        reinterpret_cast<const uint8_t *>(input.data()),
                        input.size());
  if (!len) {
    return false;
  }
  output->assign(encoded.data(), len);
  return true;
}

bool Base64Decode(const std::string_view &input, std::string *output) {
  size_t len;
  if (!EVP_DecodedLength(&len, input.size())) {
    return false;
  }
  std::vector<char> decoded(len);
  if (!EVP_DecodeBase64(reinterpret_cast<uint8_t *>(decoded.data()), &len, len,
                        reinterpret_cast<const uint8_t *>(input.data()),
                        input.size())) {
    return false;
  }
  output->assign(decoded.data(), len);
  return true;
}

}  // namespace string_util
BSSL_NAMESPACE_END
