/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

#include <stdint.h>
#include <limits>
#include <regex>

#include <gtest/gtest.h>

#include <geode/DataOutput.hpp>
#include <geode/CacheFactory.hpp>

#include "gtest_extensions.h"
#include "ByteArrayFixture.hpp"
#include "DataOutputInternal.hpp"
#include "SerializationRegistry.hpp"
#include "DataInputInternal.hpp"
#include "DataOutputInternal.hpp"

namespace {

using apache::geode::client::ByteArray;
using apache::geode::client::CacheableString;
using apache::geode::client::DataInputInternal;
using apache::geode::client::DataOutput;
using apache::geode::client::DataOutputInternal;
using apache::geode::client::SerializationRegistry;

class TestDataOutput : public DataOutputInternal {
 public:
  TestDataOutput()
      : DataOutputInternal(), m_byteArray(nullptr), m_serializationRegistry() {
    // NOP
  }

  ~TestDataOutput() noexcept override {
    delete m_byteArray;
    m_byteArray = nullptr;
  }

  const ByteArray& getByteArray() const {
    if (!m_byteArray) {
      m_byteArray = new ByteArray(getBuffer(), getBufferLength());
    }
    return *m_byteArray;
  }

 protected:
  virtual const SerializationRegistry& getSerializationRegistry()
      const override {
    return m_serializationRegistry;
  }

 private:
  mutable ByteArray* m_byteArray;
  SerializationRegistry m_serializationRegistry;
};

class CacheableStringTests : public ::testing::Test, public ByteArrayFixture {
 public:
 protected:
};

inline std::string to_hex(const uint8_t* bytes, size_t len) {
  std::stringstream ss;
  ss << std::setfill('0') << std::hex;
  for (size_t i(0); i < len; ++i) {
    ss << std::setw(2) << (int)bytes[i];
  }
  return ss.str();
}

inline std::string to_hex(const DataOutput& out) {
  return to_hex(out.getBuffer(), out.getBufferLength());
}

TEST_F(CacheableStringTests, CreateFromStdStringRValue) {
  auto s = std::string("You had me at meat tornado.");
  auto m = s;
  auto c = CacheableString::create(std::move(m));

  ASSERT_TRUE(m.empty());
  ASSERT_EQ(s, c->value());
}

TEST_F(CacheableStringTests, CreateFromStdStringLValue) {
  auto s = std::string("You had me at meat tornado.");
  auto c = CacheableString::create(s);

  ASSERT_FALSE(s.empty());
  ASSERT_EQ(s, c->value());
}

TEST_F(CacheableStringTests, TestToDataAscii) {
  auto origStr = CacheableString::create("You had me at meat tornado.");
  DataOutputInternal out;
  origStr->toData(out);

  EXPECT_EQ("001b596f7520686164206d65206174206d65617420746f726e61646f2e",
            to_hex(out));
}

TEST_F(CacheableStringTests, TestFromDataAscii) {
  std::string utf8("You had me at meat tornado.");
  auto origStr = CacheableString::create(utf8.c_str());
  DataOutputInternal out;
  origStr->toData(out);

  auto str = std::dynamic_pointer_cast<CacheableString>(
      CacheableString::createUTFDeserializable());
  DataInputInternal in(out.getBuffer(), out.getBufferLength());
  str->fromData(in);

  EXPECT_EQ(utf8, str->value());
}

TEST_F(CacheableStringTests, TestToDataNonAscii) {
  auto origStr = CacheableString::create(u8"You had me at meat tornad\u00F6.");
  DataOutputInternal out;
  origStr->toData(out);

  EXPECT_EQ("001c596f7520686164206d65206174206d65617420746f726e6164c3b62e",
            to_hex(out));
}

TEST_F(CacheableStringTests, TestFromDataNonAscii) {
  std::string utf8(u8"You had me at meat tornad\u00F6.");
  auto origStr = CacheableString::create(utf8);
  DataOutputInternal out;
  origStr->toData(out);

  auto str = std::dynamic_pointer_cast<CacheableString>(
      CacheableString::createUTFDeserializable());
  DataInputInternal in(out.getBuffer(), out.getBufferLength());
  str->fromData(in);

  EXPECT_EQ(utf8, str->value());
}

TEST_F(CacheableStringTests, TestToDataAsciiHuge) {
  size_t originalLen = std::numeric_limits<uint16_t>::max();
  std::string utf8(originalLen, 'a');
  utf8.append("a");
  originalLen++;

  auto origStr = CacheableString::create(utf8.c_str());
  TestDataOutput out;
  origStr->toData(out);

  auto&& bufLen = originalLen + 4;  // strLen (unit32_t)
  EXPECT_EQ(bufLen, out.getBufferLength());

  // 0x00010000 - length
  // 0x61 - first 'a'
  // EXPECT_MATCH("0001000061.*61", to_hex(out));
  EXPECT_BYTEARRAY_EQ("0001000061\\h{131068}61", out.getByteArray());
}

TEST_F(CacheableStringTests, TestFromDataAsciiHuge) {
  std::string utf8(std::numeric_limits<uint16_t>::max(), 'a');
  utf8.append("a");

  auto origStr = CacheableString::create(utf8.c_str());
  DataOutputInternal out;
  origStr->toData(out);

  auto str = std::dynamic_pointer_cast<CacheableString>(
      CacheableString::createDeserializableHuge());
  DataInputInternal in(out.getBuffer(), out.getBufferLength());
  str->fromData(in);

  EXPECT_EQ(utf8, str->value());
}

TEST_F(CacheableStringTests, TestToDataNonAsciiHuge) {
  std::string utf8(std::numeric_limits<uint16_t>::max(), 'a');
  utf8.append(u8"\u00E4");
  auto&& utf16 =
      std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>{}
          .from_bytes(utf8);

  auto origStr = CacheableString::create(utf8.c_str());
  TestDataOutput out;
  origStr->toData(out);

  // utf-16 units length (unit32_t) + utf-16 units (uint16_t*)
  auto&& bufLen = 4 + utf16.length() * sizeof(uint16_t);
  EXPECT_EQ(bufLen, out.getBufferLength());

  // 0x00010000 - length
  // 0x0061 - first 'a'
  // 0x006100E4 - last 'a\u00e4'
  // EXPECT_MATCH("000100000061.*006100e4", to_hex(out));
  EXPECT_BYTEARRAY_EQ("000100000061\\h{262132}006100E4", out.getByteArray());
}

TEST_F(CacheableStringTests, TestFromDataNonAsciiHuge) {
  std::string utf8(std::numeric_limits<uint16_t>::max(), 'a');
  utf8.append(u8"\u00E4");

  auto origStr = CacheableString::create(utf8);
  DataOutputInternal out;
  origStr->toData(out);

  auto str = std::dynamic_pointer_cast<CacheableString>(
      CacheableString::createUTFDeserializableHuge());
  DataInputInternal in(out.getBuffer(), out.getBufferLength());
  str->fromData(in);

  EXPECT_EQ(utf8, str->value());
}

}  // namespace
