#include <gtest/gtest.h>

#include <initializer_list>
#include <string>
#include <string_view>

#include "base/internal/strutils.h"

namespace {

const std::string replacement = "\xef\xbf\xbd";

std::string bytes(std::initializer_list<unsigned char> values) {
  std::string result;
  result.reserve(values.size());
  for (auto value : values) {
    result.push_back(static_cast<char>(value));
  }
  return result;
}

}  // namespace

TEST(StrutilsTest, LeavesValidUtf8Unchanged) {
  const auto input = bytes({'a', 0xe2, 0x82, 0xac, 'b'});
  EXPECT_EQ(u8_sanitize(input), input);
}

TEST(StrutilsTest, ReplacesMalformedUtf8) {
  EXPECT_EQ(u8_sanitize(bytes({'a', 0xff, 'b'})), "a" + replacement + "b");
  EXPECT_EQ(u8_sanitize(bytes({0xe2, 0x82})), replacement);
  EXPECT_EQ(u8_sanitize(bytes({0xc0, 0xaf})), replacement);
  EXPECT_EQ(u8_sanitize(bytes({0x80, 0x80})), replacement + replacement);
}

TEST(StrutilsTest, PreservesEmbeddedNullBytes) {
  const auto input = bytes({'a', 0x00, 0xff, 'b'});
  const auto expected = std::string("a\0", 2) + replacement + "b";
  EXPECT_EQ(u8_sanitize(std::string_view(input.data(), input.size())), expected);
}
