#include "flatbuffers/reflection.h"
#include "gtest/gtest.h"

#include "aos/json_to_flatbuffer.h"
#include "aos/json_to_flatbuffer_generated.h"
#include "aos/testing/path.h"
#include "aos/util/file.h"

namespace aos {
namespace testing {

using aos::testing::ArtifactPath;

class FlatbufferIntrospectionTest : public ::testing::Test {
 public:
  FlatbufferIntrospectionTest()
      : schema_data_(FileToFlatbuffer<reflection::Schema>(
            ArtifactPath("aos/json_to_flatbuffer.bfbs"))) {
    schema_ = reflection::GetSchema(schema_data_.span().data());
  }

 protected:
  FlatbufferVector<reflection::Schema> schema_data_;
  const reflection::Schema *schema_;
};

TEST_F(FlatbufferIntrospectionTest, IntegerTest) {
  flatbuffers::FlatBufferBuilder builder;
  ConfigurationBuilder config_builder(builder);

  config_builder.add_foo_byte(-5);
  config_builder.add_foo_ubyte(5);
  config_builder.add_foo_bool(true);

  config_builder.add_foo_short(-10);
  config_builder.add_foo_ushort(10);

  config_builder.add_foo_int(-20);
  config_builder.add_foo_uint(20);

  config_builder.add_foo_long(-100);
  config_builder.add_foo_ulong(100);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out,
            "{\"foo_bool\": true, \"foo_byte\": -5, \"foo_int\": -20, "
            "\"foo_long\": -100, \"foo_short\": -10, \"foo_ubyte\": 5, "
            "\"foo_uint\": 20, \"foo_ulong\": 100, \"foo_ushort\": 10}");
}

TEST_F(FlatbufferIntrospectionTest, FloatTest) {
  flatbuffers::FlatBufferBuilder builder;
  ConfigurationBuilder config_builder(builder);

  config_builder.add_foo_float(1.0 / 3.0);
  config_builder.add_foo_double(5.0 / 9.0);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out,
            "{\"foo_double\": 0.555555555555556, \"foo_float\": 0.333333}");
}

TEST_F(FlatbufferIntrospectionTest, NanFloatTest) {
  flatbuffers::FlatBufferBuilder builder;
  ConfigurationBuilder config_builder(builder);

  config_builder.add_foo_float(std::numeric_limits<float>::quiet_NaN());
  config_builder.add_foo_double(std::numeric_limits<double>::quiet_NaN());

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out, "{\"foo_double\": null, \"foo_float\": null}");
}

TEST_F(FlatbufferIntrospectionTest, VectorScalarTest) {
  flatbuffers::FlatBufferBuilder builder;

  // Flatbuffers don't like creating vectors simultaneously with table, so do
  // first.
  auto foo_bytes = builder.CreateVector<int8_t>({-3, -2, -1, 0, 1, 2, 3});
  auto foo_ubytes = builder.CreateVector<uint8_t>({0, 1, 2, 3, 4, 5, 6});
  auto foo_bools = builder.CreateVector<uint8_t>({true, false, true, false});

  auto foo_shorts =
      builder.CreateVector<int16_t>({-30, -20, -10, 0, 10, 20, 30});
  auto foo_ushorts =
      builder.CreateVector<uint16_t>({0, 10, 20, 30, 40, 50, 60});

  auto foo_ints =
      builder.CreateVector<int32_t>({-300, -200, -100, 0, 100, 200, 300});
  auto foo_uints =
      builder.CreateVector<uint32_t>({0, 100, 200, 300, 400, 500, 600});

  auto foo_longs =
      builder.CreateVector<int64_t>({-3000, -2000, -1000, 0, 1000, 2000, 3000});
  auto foo_ulongs =
      builder.CreateVector<uint64_t>({0, 1000, 2000, 3000, 4000, 5000, 6000});

  auto foo_floats =
      builder.CreateVector<float>({0.0, 1.0 / 9.0, 2.0 / 9.0, 3.0 / 9.0});
  auto foo_doubles =
      builder.CreateVector<double>({0, 1.0 / 9.0, 2.0 / 9.0, 3.0 / 9.0});

  ConfigurationBuilder config_builder(builder);
  config_builder.add_vector_foo_byte(foo_bytes);
  config_builder.add_vector_foo_ubyte(foo_ubytes);
  config_builder.add_vector_foo_bool(foo_bools);

  config_builder.add_vector_foo_short(foo_shorts);
  config_builder.add_vector_foo_ushort(foo_ushorts);

  config_builder.add_vector_foo_int(foo_ints);
  config_builder.add_vector_foo_uint(foo_uints);

  config_builder.add_vector_foo_long(foo_longs);
  config_builder.add_vector_foo_ulong(foo_ulongs);

  config_builder.add_vector_foo_float(foo_floats);
  config_builder.add_vector_foo_double(foo_doubles);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(
      out,
      "{\"vector_foo_bool\": [true, false, true, false], \"vector_foo_byte\": "
      "[-3, -2, -1, 0, 1, 2, 3], \"vector_foo_double\": [0, 0.111111111111111, "
      "0.222222222222222, 0.333333333333333], \"vector_foo_float\": [0, "
      "0.111111, 0.222222, 0.333333], \"vector_foo_int\": [-300, -200, -100, "
      "0, 100, 200, 300], \"vector_foo_long\": [-3000, -2000, -1000, 0, 1000, "
      "2000, 3000], \"vector_foo_short\": [-30, -20, -10, 0, 10, 20, 30], "
      "\"vector_foo_ubyte\": [0, 1, 2, 3, 4, 5, 6], \"vector_foo_uint\": [0, "
      "100, 200, 300, 400, 500, 600], \"vector_foo_ulong\": [0, 1000, 2000, "
      "3000, 4000, 5000, 6000], \"vector_foo_ushort\": [0, 10, 20, 30, 40, 50, "
      "60]}");
}

TEST_F(FlatbufferIntrospectionTest, StringTest) {
  flatbuffers::FlatBufferBuilder builder;

  auto foo_string = builder.CreateString("I <3 FlatBuffers!");

  ConfigurationBuilder config_builder(builder);
  config_builder.add_foo_string(foo_string);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out, "{\"foo_string\": \"I <3 FlatBuffers!\"}");
}

TEST_F(FlatbufferIntrospectionTest, EnumTest) {
  flatbuffers::FlatBufferBuilder builder;

  ConfigurationBuilder config_builder(builder);
  config_builder.add_foo_enum(BaseType::UShort);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out, "{\"foo_enum\": \"UShort\"}");
}

TEST_F(FlatbufferIntrospectionTest, EnumWithUnknownValueTest) {
  flatbuffers::FlatBufferBuilder builder;

  ConfigurationBuilder config_builder(builder);
  // 123 is not part of the enum.  We expect it to be represented by null in
  // the json.
  config_builder.fbb_.AddElement<uint8_t>(Configuration::VT_FOO_ENUM, 123, 0);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out, "{\"foo_enum\": 123}");
}

TEST_F(FlatbufferIntrospectionTest, VectorStringTest) {
  flatbuffers::FlatBufferBuilder builder;

  std::vector<std::vector<std::string>> words{
      {"abc", "acb"}, {"bac", "bca"}, {"cab", "cba"}};
  std::vector<flatbuffers::Offset<
      flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>>>
      strings;

  for (const auto &v : words) {
    strings.push_back(builder.CreateVectorOfStrings(v));
  }

  std::vector<flatbuffers::Offset<VectorOfStrings>> sub_vectors;

  for (const auto &v : strings) {
    VectorOfStringsBuilder v_builder(builder);
    v_builder.add_str(v);
    sub_vectors.push_back(v_builder.Finish());
  }

  auto foo_vov = builder.CreateVector(sub_vectors);

  VectorOfVectorOfStringBuilder vov_builder(builder);
  vov_builder.add_v(foo_vov);
  auto vov = vov_builder.Finish();

  ConfigurationBuilder config_builder(builder);
  config_builder.add_vector_foo_string(strings[0]);
  config_builder.add_vov(vov);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out,
            "{\"vector_foo_string\": [\"abc\", \"acb\"], \"vov\": {\"v\": "
            "[{\"str\": [\"abc\", \"acb\"]}, {\"str\": [\"bac\", \"bca\"]}, "
            "{\"str\": [\"cab\", \"cba\"]}]}}");
}

TEST_F(FlatbufferIntrospectionTest, TableTest) {
  flatbuffers::FlatBufferBuilder builder;

  auto foo_string2 = builder.CreateString("Nested Config String");
  auto foo_bytes2 = builder.CreateVector<int8_t>({6, 7, 8, 9, 10});

  ConfigurationBuilder config_builder2(builder);
  config_builder2.add_foo_byte(10);
  config_builder2.add_foo_string(foo_string2);
  config_builder2.add_vector_foo_byte(foo_bytes2);

  flatbuffers::Offset<Configuration> config_2 = config_builder2.Finish();

  auto foo_string = builder.CreateString("Root Config String");
  auto foo_bytes = builder.CreateVector<int8_t>({0, 1, 2, 3, 4, 5});

  ConfigurationBuilder config_builder(builder);
  config_builder.add_nested_config(config_2);
  config_builder.add_foo_byte(5);
  config_builder.add_foo_string(foo_string);
  config_builder.add_vector_foo_byte(foo_bytes);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out,
            "{\"foo_byte\": 5, \"foo_string\": \"Root Config String\", "
            "\"nested_config\": {\"foo_byte\": 10, \"foo_string\": \"Nested "
            "Config String\", \"vector_foo_byte\": [6, 7, 8, 9, 10]}, "
            "\"vector_foo_byte\": [0, 1, 2, 3, 4, 5]}");
}

TEST_F(FlatbufferIntrospectionTest, StructTest) {
  flatbuffers::FlatBufferBuilder builder;

  FooStructNested foo_struct2(10);

  FooStruct foo_struct(5, foo_struct2);

  ConfigurationBuilder config_builder(builder);
  config_builder.add_foo_struct(&foo_struct);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out,
            "{\"foo_struct\": {\"foo_byte\": 5, \"nested_struct\": "
            "{\"foo_byte\": 10}}}");
}

TEST_F(FlatbufferIntrospectionTest, VectorStructTest) {
  flatbuffers::FlatBufferBuilder builder;

  FooStructNested foo_struct2(1);

  auto structs = builder.CreateVectorOfStructs(
      std::vector<FooStruct>({{5, foo_struct2}, {10, foo_struct2}}));

  ConfigurationBuilder config_builder(builder);
  config_builder.add_vector_foo_struct(structs);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out,
            "{\"vector_foo_struct\": [{\"foo_byte\": 5, \"nested_struct\": "
            "{\"foo_byte\": 1}}, {\"foo_byte\": 10, \"nested_struct\": "
            "{\"foo_byte\": 1}}]}");
}

TEST_F(FlatbufferIntrospectionTest, VectorEnumTest) {
  flatbuffers::FlatBufferBuilder builder;

  auto enums = builder.CreateVector<BaseType>(
      {BaseType::UShort, BaseType::Obj, BaseType::UInt});

  ConfigurationBuilder config_builder(builder);
  config_builder.add_vector_foo_enum(enums);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out, "{\"vector_foo_enum\": [\"UShort\", \"Obj\", \"UInt\"]}");
}

TEST_F(FlatbufferIntrospectionTest, StructEnumTest) {
  flatbuffers::FlatBufferBuilder builder;

  StructEnum foo_struct(BaseType::UShort);

  ConfigurationBuilder config_builder(builder);
  config_builder.add_foo_struct_enum(&foo_struct);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());

  EXPECT_EQ(out, "{\"foo_struct_enum\": {\"foo_enum\": \"UShort\"}}");
}

TEST_F(FlatbufferIntrospectionTest, StringEscapeTest) {
  flatbuffers::FlatBufferBuilder builder;

  auto foo_string = builder.CreateString("\"\\\b\f\n\r\t");

  ConfigurationBuilder config_builder(builder);
  config_builder.add_foo_string(foo_string);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer());
  EXPECT_EQ(out, "{\"foo_string\": \"\\\"\\\\\\b\\f\\n\\r\\t\"}");
}

TEST_F(FlatbufferIntrospectionTest, TrimmedVector) {
  flatbuffers::FlatBufferBuilder builder;

  std::vector<int32_t> contents;
  for (int i = 0; i < 101; ++i) {
    contents.push_back(i);
  }
  const auto contents_offset = builder.CreateVector(contents);

  ConfigurationBuilder config_builder(builder);
  config_builder.add_vector_foo_int(contents_offset);

  builder.Finish(config_builder.Finish());

  std::string out =
      FlatbufferToJson(schema_, builder.GetBufferPointer(),
                       {.multi_line = false, .max_vector_size = 100});
  EXPECT_EQ(out, "{\"vector_foo_int\": [ \"... 101 elements ...\" ]}");
}

TEST_F(FlatbufferIntrospectionTest, MultilineTest) {
  flatbuffers::FlatBufferBuilder builder;
  ConfigurationBuilder config_builder(builder);

  config_builder.add_foo_bool(true);
  config_builder.add_foo_int(-20);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer(),
                                     {.multi_line = true});

  EXPECT_EQ(out,
            "{\n"
            "  \"foo_bool\": true,\n"
            "  \"foo_int\": -20\n"
            "}");
}

TEST_F(FlatbufferIntrospectionTest, MultilineStructTest) {
  flatbuffers::FlatBufferBuilder builder;
  ConfigurationBuilder config_builder(builder);

  FooStructNested foo_struct2(10);
  FooStruct foo_struct(5, foo_struct2);

  config_builder.add_foo_struct(&foo_struct);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer(),
                                     {.multi_line = true});

  EXPECT_EQ(out,
            "{\n"
            "  \"foo_struct\": {\n"
            "    \"foo_byte\": 5,\n"
            "    \"nested_struct\": {\"foo_byte\": 10}\n"
            "  }\n"
            "}");
}

TEST_F(FlatbufferIntrospectionTest, MultilineVectorStructTest) {
  flatbuffers::FlatBufferBuilder builder;

  FooStructNested foo_struct2(1);

  auto structs = builder.CreateVectorOfStructs(
      std::vector<FooStruct>({{5, foo_struct2}, {10, foo_struct2}}));

  ConfigurationBuilder config_builder(builder);
  config_builder.add_vector_foo_struct(structs);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer(),
                                     {.multi_line = true});

  EXPECT_EQ(out,
            "{\n"
            "  \"vector_foo_struct\": [\n"
            "    {\n"
            "      \"foo_byte\": 5,\n"
            "      \"nested_struct\": {\"foo_byte\": 1}\n"
            "    },\n"
            "    {\n"
            "      \"foo_byte\": 10,\n"
            "      \"nested_struct\": {\"foo_byte\": 1}\n"
            "    }\n"
            "  ]\n"
            "}");
}

TEST_F(FlatbufferIntrospectionTest, MultilineVectorScalarTest) {
  flatbuffers::FlatBufferBuilder builder;

  // Flatbuffers don't like creating vectors simultaneously with table, so do
  // first.
  auto foo_ints =
      builder.CreateVector<int32_t>({-300, -200, -100, 0, 100, 200, 300});

  auto foo_floats =
      builder.CreateVector<float>({0.0, 1.0 / 9.0, 2.0 / 9.0, 3.0 / 9.0});
  auto foo_doubles =
      builder.CreateVector<double>({0, 1.0 / 9.0, 2.0 / 9.0, 3.0 / 9.0});

  ConfigurationBuilder config_builder(builder);

  config_builder.add_vector_foo_int(foo_ints);
  config_builder.add_vector_foo_float(foo_floats);
  config_builder.add_vector_foo_double(foo_doubles);

  builder.Finish(config_builder.Finish());

  std::string out = FlatbufferToJson(schema_, builder.GetBufferPointer(),
                                     {.multi_line = true});

  EXPECT_EQ(out,
            "{\n"
            "  \"vector_foo_double\": [0, 0.111111111111111, "
            "0.222222222222222, 0.333333333333333],\n"
            "  \"vector_foo_float\": [0, 0.111111, 0.222222, 0.333333],\n"
            "  \"vector_foo_int\": [-300, -200, -100, 0, 100, 200, 300]\n"
            "}");
}

// Tests that a nullptr buffer prints nullptr.
TEST_F(FlatbufferIntrospectionTest, NullptrData) {
  EXPECT_EQ("null", FlatbufferToJson(schema_, nullptr));
}

// Tests that a null schema gets caught.
TEST(FlatbufferIntrospectionDeathTest, NullSchema) {
  EXPECT_DEATH(
      {
        FlatbufferToJson(static_cast<const reflection::Schema *>(nullptr),
                         nullptr);
      },
      "Need to provide a schema");
}

}  // namespace testing
}  // namespace aos
