#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::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.5555555555555556, \"foo_float\": 0.33333334 }");
}

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\": nan, \"foo_float\": nan }");
}

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.1111111111111111, 0.2222222222222222, 0.3333333333333333 ], "
      "\"vector_foo_float\": [ 0, 0.11111111, 0.22222222, 0.33333334 ], "
      "\"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.1111111111111111, "
      "0.2222222222222222, 0.3333333333333333 ],\n  \"vector_foo_float\": [ 0, "
      "0.11111111, 0.22222222, 0.33333334 ],\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 aos::testing
