#include "flexbuffers_test.h"

#include <memory>
#include <limits>

#include "flatbuffers/flexbuffers.h"
#include "flatbuffers/idl.h"
#include "is_quiet_nan.h"
#include "test_assert.h"

namespace flatbuffers {
namespace tests {

// Shortcuts for the infinity.
static const auto infinity_d = std::numeric_limits<double>::infinity();

static bool IsAligned(const void* ptr, std::size_t alignment) {
  void* p = const_cast<void*>(ptr);
  std::size_t space = 2 * alignment;
  void* q = std::align(alignment, alignment, p, space);
  return q != nullptr && p == ptr && space == 2 * alignment;
}

void FlexBuffersTest() {
  flexbuffers::Builder slb(512,
                           flexbuffers::BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);

  // Write the equivalent of:
  // { vec: [ -100, "Fred", 4.0, false ], bar: [ 1, 2, 3 ], bar3: [ 1, 2, 3 ],
  // foo: 100, bool: true, mymap: { foo: "Fred" } }

  // It's possible to do this without std::function support as well.
  slb.Map([&]() {
    slb.Vector("vec", [&]() {
      slb += -100;  // Equivalent to slb.Add(-100) or slb.Int(-100);
      slb += "Fred";
      slb.IndirectFloat(4.0f);
      auto i_f = slb.LastValue();
      uint8_t blob[] = {77};
      uint32_t aligned_blob[] = {88, 99};
      slb.Blob(blob, sizeof blob);
      slb.AlignedBlob(aligned_blob, sizeof aligned_blob,
                      flexbuffers::BIT_WIDTH_32);
      slb += false;
      slb.ReuseValue(i_f);
    });
    int ints[] = {1, 2, 3};
    slb.Vector("bar", ints, 3);
    slb.FixedTypedVector("bar3", ints, 3);
    bool bools[] = {true, false, true, false};
    slb.Vector("bools", bools, 4);
    slb.Bool("bool", true);
    slb.Double("foo", 100);
    slb.Map("mymap", [&]() {
      slb.String("foo", "Fred");  // Testing key and string reuse.
    });
  });
  slb.Finish();

  // clang-format off
  #ifdef FLATBUFFERS_TEST_VERBOSE
    for (size_t i = 0; i < slb.GetBuffer().size(); i++)
      printf("%d ", slb.GetBuffer().data()[i]);
    printf("\n");
  #endif
  // clang-format on

  std::vector<uint8_t> reuse_tracker;
  TEST_EQ(flexbuffers::VerifyBuffer(slb.GetBuffer().data(),
                                    slb.GetBuffer().size(), &reuse_tracker),
          true);

  auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
  TEST_EQ(map.size(), 7);
  auto vec = map["vec"].AsVector();
  TEST_EQ(vec.size(), 7);
  TEST_EQ(vec[0].AsInt64(), -100);
  TEST_EQ_STR(vec[1].AsString().c_str(), "Fred");
  TEST_EQ(vec[1].AsInt64(), 0);  // Number parsing failed.
  TEST_EQ(vec[2].AsDouble(), 4.0);
  TEST_EQ(vec[2].AsString().IsTheEmptyString(), true);  // Wrong Type.
  TEST_EQ_STR(vec[2].AsString().c_str(), "");     // This still works though.
  TEST_EQ_STR(vec[2].ToString().c_str(), "4.0");  // Or have it converted.
  // Few tests for templated version of As.
  TEST_EQ(vec[0].As<int64_t>(), -100);
  TEST_EQ_STR(vec[1].As<std::string>().c_str(), "Fred");
  TEST_EQ(vec[1].As<int64_t>(), 0);  // Number parsing failed.
  TEST_EQ(vec[2].As<double>(), 4.0);
  // Test that the blob can be accessed.
  TEST_EQ(vec[3].IsBlob(), true);
  auto blob = vec[3].AsBlob();
  TEST_EQ(blob.size(), 1);
  TEST_EQ(blob.data()[0], 77);
  TEST_EQ(vec[4].IsBlob(), true);
  auto aligned_blob = vec[4].AsBlob();
  TEST_EQ(aligned_blob.size(), 8);
  TEST_EQ(reinterpret_cast<const uint32_t*>(aligned_blob.data())[0], 88);
  TEST_EQ(reinterpret_cast<const uint32_t*>(aligned_blob.data())[1], 99);
  TEST_EQ(IsAligned(aligned_blob.data(), 4), true);
  TEST_EQ(vec[5].IsBool(), true);   // Check if type is a bool
  TEST_EQ(vec[5].AsBool(), false);  // Check if value is false
  TEST_EQ(vec[6].AsDouble(), 4.0);  // This is shared with vec[2] !
  auto tvec = map["bar"].AsTypedVector();
  TEST_EQ(tvec.size(), 3);
  TEST_EQ(tvec[2].AsInt8(), 3);
  auto tvec3 = map["bar3"].AsFixedTypedVector();
  TEST_EQ(tvec3.size(), 3);
  TEST_EQ(tvec3[2].AsInt8(), 3);
  TEST_EQ(map["bool"].AsBool(), true);
  auto tvecb = map["bools"].AsTypedVector();
  TEST_EQ(tvecb.ElementType(), flexbuffers::FBT_BOOL);
  TEST_EQ(map["foo"].AsUInt8(), 100);
  TEST_EQ(map["unknown"].IsNull(), true);
  auto mymap = map["mymap"].AsMap();
  // These should be equal by pointer equality, since key and value are shared.
  TEST_EQ(mymap.Keys()[0].AsKey(), map.Keys()[4].AsKey());
  TEST_EQ(mymap.Values()[0].AsString().c_str(), vec[1].AsString().c_str());
  // We can mutate values in the buffer.
  TEST_EQ(vec[0].MutateInt(-99), true);
  TEST_EQ(vec[0].AsInt64(), -99);
  TEST_EQ(vec[1].MutateString("John"), true);  // Size must match.
  TEST_EQ_STR(vec[1].AsString().c_str(), "John");
  TEST_EQ(vec[1].MutateString("Alfred"), false);  // Too long.
  TEST_EQ(vec[2].MutateFloat(2.0f), true);
  TEST_EQ(vec[2].AsFloat(), 2.0f);
  TEST_EQ(vec[2].MutateFloat(3.14159), false);  // Double does not fit in float.
  TEST_EQ(vec[5].AsBool(), false);              // Is false before change
  TEST_EQ(vec[5].MutateBool(true), true);       // Can change a bool
  TEST_EQ(vec[5].AsBool(), true);               // Changed bool is now true

  // Parse from JSON:
  flatbuffers::Parser parser;
  slb.Clear();
  auto jsontest = "{ a: [ 123, 456.0 ], b: \"hello\", c: true, d: false }";
  TEST_EQ(parser.ParseFlexBuffer(jsontest, nullptr, &slb), true);
  TEST_EQ(flexbuffers::VerifyBuffer(slb.GetBuffer().data(),
                                    slb.GetBuffer().size(), &reuse_tracker),
          true);
  auto jroot = flexbuffers::GetRoot(slb.GetBuffer());
  auto jmap = jroot.AsMap();
  auto jvec = jmap["a"].AsVector();
  TEST_EQ(jvec[0].AsInt64(), 123);
  TEST_EQ(jvec[1].AsDouble(), 456.0);
  TEST_EQ_STR(jmap["b"].AsString().c_str(), "hello");
  TEST_EQ(jmap["c"].IsBool(), true);   // Parsed correctly to a bool
  TEST_EQ(jmap["c"].AsBool(), true);   // Parsed correctly to true
  TEST_EQ(jmap["d"].IsBool(), true);   // Parsed correctly to a bool
  TEST_EQ(jmap["d"].AsBool(), false);  // Parsed correctly to false
  // And from FlexBuffer back to JSON:
  auto jsonback = jroot.ToString();
  TEST_EQ_STR(jsontest, jsonback.c_str());
  // With indentation:
  std::string jsonback_indented;
  jroot.ToString(true, false, jsonback_indented, true, 0, "  ");
  auto jsontest_indented =
      "{\n  a: [\n    123,\n    456.0\n  ],\n  b: \"hello\",\n  c: true,\n  d: "
      "false\n}";
  TEST_EQ_STR(jsontest_indented, jsonback_indented.c_str());

  slb.Clear();
  slb.Vector([&]() {
    for (int i = 0; i < 130; ++i) slb.Add(static_cast<uint8_t>(255));
    slb.Vector([&]() {
      for (int i = 0; i < 130; ++i) slb.Add(static_cast<uint8_t>(255));
      slb.Vector([] {});
    });
  });
  slb.Finish();
  TEST_EQ(slb.GetSize(), 664);
}

void FlexBuffersReuseBugTest() {
  flexbuffers::Builder slb;
  slb.Map([&]() {
    slb.Vector("vec", [&]() {});
    slb.Bool("bool", true);
  });
  slb.Finish();
  std::vector<uint8_t> reuse_tracker;
  // This would fail before, since the reuse_tracker would use the address of
  // the vector reference to check for reuse, but in this case we have an empty
  // vector, and since the size field is before the pointer, its address is the
  // same as thing after it, the key "bool".
  // We fix this by using the address of the size field for tracking reuse.
  TEST_EQ(flexbuffers::VerifyBuffer(slb.GetBuffer().data(),
                                    slb.GetBuffer().size(), &reuse_tracker),
          true);
}

void FlexBuffersFloatingPointTest() {
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
  flexbuffers::Builder slb(512,
                           flexbuffers::BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
  // Parse floating-point values from JSON:
  flatbuffers::Parser parser;
  slb.Clear();
  auto jsontest =
      "{ a: [1.0, nan, inf, infinity, -inf, +inf, -infinity, 8.0] }";
  TEST_EQ(parser.ParseFlexBuffer(jsontest, nullptr, &slb), true);
  auto jroot = flexbuffers::GetRoot(slb.GetBuffer());
  TEST_EQ(flexbuffers::VerifyBuffer(slb.GetBuffer().data(),
                                    slb.GetBuffer().size(), nullptr),
          true);
  auto jmap = jroot.AsMap();
  auto jvec = jmap["a"].AsVector();
  TEST_EQ(8, jvec.size());
  TEST_EQ(1.0, jvec[0].AsDouble());
  TEST_ASSERT(is_quiet_nan(jvec[1].AsDouble()));
  TEST_EQ(infinity_d, jvec[2].AsDouble());
  TEST_EQ(infinity_d, jvec[3].AsDouble());
  TEST_EQ(-infinity_d, jvec[4].AsDouble());
  TEST_EQ(+infinity_d, jvec[5].AsDouble());
  TEST_EQ(-infinity_d, jvec[6].AsDouble());
  TEST_EQ(8.0, jvec[7].AsDouble());
#endif
}

void FlexBuffersDeprecatedTest() {
  // FlexBuffers as originally designed had a flaw involving the
  // FBT_VECTOR_STRING datatype, and this test documents/tests the fix for it.
  // Discussion: https://github.com/google/flatbuffers/issues/5627
  flexbuffers::Builder slb;
  // FBT_VECTOR_* are "typed vectors" where all elements are of the same type.
  // Problem is, when storing FBT_STRING elements, it relies on that type to
  // get the bit-width for the size field of the string, which in this case
  // isn't present, and instead defaults to 8-bit. This means that any strings
  // stored inside such a vector, when accessed thru the old API that returns
  // a String reference, will appear to be truncated if the string stored is
  // actually >=256 bytes.
  std::string test_data(300, 'A');
  auto start = slb.StartVector();
  // This one will have a 16-bit size field.
  slb.String(test_data);
  // This one will have an 8-bit size field.
  slb.String("hello");
  // We're asking this to be serialized as a typed vector (true), but not
  // fixed size (false). The type will be FBT_VECTOR_STRING with a bit-width
  // of whatever the offsets in the vector need, the bit-widths of the strings
  // are not stored(!) <- the actual design flaw.
  // Note that even in the fixed code, we continue to serialize the elements of
  // FBT_VECTOR_STRING as FBT_STRING, since there may be old code out there
  // reading new data that we want to continue to function.
  // Thus, FBT_VECTOR_STRING, while deprecated, will always be represented the
  // same way, the fix lies on the reading side.
  slb.EndVector(start, true, false);
  slb.Finish();
  // Verify because why not.
  TEST_EQ(flexbuffers::VerifyBuffer(slb.GetBuffer().data(),
                                    slb.GetBuffer().size(), nullptr),
          true);
  // So now lets read this data back.
  // For existing data, since we have no way of knowing what the actual
  // bit-width of the size field of the string is, we are going to ignore this
  // field, and instead treat these strings as FBT_KEY (null-terminated), so we
  // can deal with strings of arbitrary length. This of course truncates strings
  // with embedded nulls, but we think that that is preferrable over truncating
  // strings >= 256 bytes.
  auto vec = flexbuffers::GetRoot(slb.GetBuffer()).AsTypedVector();
  // Even though this was serialized as FBT_VECTOR_STRING, it is read as
  // FBT_VECTOR_KEY:
  TEST_EQ(vec.ElementType(), flexbuffers::FBT_KEY);
  // Access the long string. Previously, this would return a string of size 1,
  // since it would read the high-byte of the 16-bit length.
  // This should now correctly test the full 300 bytes, using AsKey():
  TEST_EQ_STR(vec[0].AsKey(), test_data.c_str());
  // Old code that called AsString will continue to work, as the String
  // accessor objects now use a cached size that can come from a key as well.
  TEST_EQ_STR(vec[0].AsString().c_str(), test_data.c_str());
  // Short strings work as before:
  TEST_EQ_STR(vec[1].AsKey(), "hello");
  TEST_EQ_STR(vec[1].AsString().c_str(), "hello");
  // So, while existing code and data mostly "just work" with the fixes applied
  // to AsTypedVector and AsString, what do you do going forward?
  // Code accessing existing data doesn't necessarily need to change, though
  // you could consider using AsKey instead of AsString for a) documenting
  // that you are accessing keys, or b) a speedup if you don't actually use
  // the string size.
  // For new data, or data that doesn't need to be backwards compatible,
  // instead serialize as FBT_VECTOR (call EndVector with typed = false, then
  // read elements with AsString), or, for maximum compactness, use
  // FBT_VECTOR_KEY (call slb.Key above instead, read with AsKey or AsString).
}

void ParseFlexbuffersFromJsonWithNullTest() {
  // Test nulls are handled appropriately through flexbuffers to exercise other
  // code paths of ParseSingleValue in the optional scalars change.
  // TODO(cneo): Json -> Flatbuffers test once some language can generate code
  // with optional scalars.
  {
    char json[] = "{\"opt_field\": 123 }";
    flatbuffers::Parser parser;
    flexbuffers::Builder flexbuild;
    parser.ParseFlexBuffer(json, nullptr, &flexbuild);
    auto root = flexbuffers::GetRoot(flexbuild.GetBuffer());
    TEST_EQ(root.AsMap()["opt_field"].AsInt64(), 123);
  }
  {
    char json[] = "{\"opt_field\": 123.4 }";
    flatbuffers::Parser parser;
    flexbuffers::Builder flexbuild;
    parser.ParseFlexBuffer(json, nullptr, &flexbuild);
    auto root = flexbuffers::GetRoot(flexbuild.GetBuffer());
    TEST_EQ(root.AsMap()["opt_field"].AsDouble(), 123.4);
  }
  {
    char json[] = "{\"opt_field\": null }";
    flatbuffers::Parser parser;
    flexbuffers::Builder flexbuild;
    parser.ParseFlexBuffer(json, nullptr, &flexbuild);
    auto root = flexbuffers::GetRoot(flexbuild.GetBuffer());
    TEST_ASSERT(!root.AsMap().IsTheEmptyMap());
    TEST_ASSERT(root.AsMap()["opt_field"].IsNull());
    TEST_EQ(root.ToString(), std::string("{ opt_field: null }"));
  }
}

}  // namespace tests
}  // namespace flatbuffers
