#include "aos/flatbuffer_merge.h"

#include <string_view>

#include "absl/strings/escaping.h"
#include "flatbuffers/minireflect.h"
#include "gtest/gtest.h"

#include "aos/json_to_flatbuffer.h"
#include "aos/json_to_flatbuffer_generated.h"

namespace aos::testing {

std::string_view FromFbb(const flatbuffers::FlatBufferBuilder &fbb) {
  return std::string_view(
      reinterpret_cast<const char *>(fbb.GetCurrentBufferPointer()),
      fbb.GetSize());
}

std::string_view FromFbb(const FlatbufferDetachedBuffer<Configuration> &b) {
  return std::string_view(reinterpret_cast<const char *>(b.span().data()),
                          b.span().size());
}

class FlatbufferMerge : public ::testing::Test {
 public:
  FlatbufferMerge() {}

  void ExpectMergedOutput(
      const NonSizePrefixedFlatbuffer<Configuration> &fb_merged,
      std::string_view expected_output) {
    ASSERT_NE(fb_merged.span().size(), 0u);

    const ::std::string merged_output = FlatbufferToJson(fb_merged);
    EXPECT_EQ(expected_output, merged_output);

    aos::FlatbufferDetachedBuffer<Configuration> expected_message(
        JsonToFlatbuffer(std::string(expected_output).c_str(),
                         ConfigurationTypeTable()));
    EXPECT_TRUE(
        CompareFlatBuffer(&fb_merged.message(), &expected_message.message()));
  }

  void JsonMerge(const ::std::string in1, const ::std::string in2,
                 const ::std::string out) {
    LOG(INFO) << "Merging: " << in1.c_str();
    LOG(INFO) << "Merging: " << in2.c_str();
    const FlatbufferDetachedBuffer<Configuration> fb1 = JsonToFlatbuffer(
        static_cast<const char *>(in1.c_str()), ConfigurationTypeTable());

    const ::std::string in1_nested = "{ \"nested_config\": " + in1 + " }";
    const FlatbufferDetachedBuffer<Configuration> fb1_nested =
        JsonToFlatbuffer(static_cast<const char *>(in1_nested.c_str()),
                         ConfigurationTypeTable());

    const FlatbufferDetachedBuffer<Configuration> fb2 = JsonToFlatbuffer(
        static_cast<const char *>(in2.c_str()), ConfigurationTypeTable());

    const ::std::string in2_nested = "{ \"nested_config\": " + in2 + " }";
    const FlatbufferDetachedBuffer<Configuration> fb2_nested =
        JsonToFlatbuffer(static_cast<const char *>(in2_nested.c_str()),
                         ConfigurationTypeTable());

    const ::std::string out_nested = "{ \"nested_config\": " + out + " }";

    const FlatbufferDetachedBuffer<Configuration> empty =
        JsonToFlatbuffer("{ }", ConfigurationTypeTable());

    ASSERT_NE(fb1.span().size(), 0u);
    ASSERT_NE(fb2.span().size(), 0u);
    ASSERT_NE(fb1_nested.span().size(), 0u);
    ASSERT_NE(fb2_nested.span().size(), 0u);

    // We now want to run 7 tests.
    //  in1 merged "" -> in1.
    //  in2 merged "" -> in2.
    //  "" merged in1 -> in1.
    //  "" merged in2 -> in2.
    //  nullptr merged in1 -> in1.
    //  in1 merged nullptr -> in1.
    //  in1 merged in2 -> out.

    {
      // in1 merged with "" => in1.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(fb1, empty);
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
    }

    {
      // in2 merged with "" => in2.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(fb2, empty);
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in2, FlatbufferToJson(fb_merged));
    }

    {
      // "" merged with in1 => in1.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(empty, fb1);
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
    }

    {
      // "" merged with in2 => in2.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(empty, fb2);
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in2, FlatbufferToJson(fb_merged));
    }

    {
      // nullptr merged with in1 => in1.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(nullptr, &fb1.message());
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
    }

    {
      // in1 merged with nullptr => in1.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(&fb1.message(), nullptr);
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
    }

    {
      // in1 merged with in2 => out.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(fb1, fb2);

      ExpectMergedOutput(fb_merged, out);
    }

    // Test all the different merge methods:
    ExpectMergedOutput(MergeFlatBuffers<Configuration>(fb1, fb2), out);
    {
      flatbuffers::FlatBufferBuilder fbb;
      fbb.ForceDefaults(true);
      fbb.Finish(MergeFlatBuffers(
          ConfigurationTypeTable(),
          reinterpret_cast<const flatbuffers::Table *>(&fb1.message()),
          reinterpret_cast<const flatbuffers::Table *>(&fb2.message()), &fbb));
      FlatbufferDetachedBuffer<Configuration> fb(fbb.Release());
      ExpectMergedOutput(fb, out);
    }
    {
      flatbuffers::FlatBufferBuilder fbb;
      fbb.ForceDefaults(true);
      fbb.Finish(MergeFlatBuffers<Configuration>(&fb1.message(), &fb2.message(),
                                                 &fbb));
      FlatbufferDetachedBuffer<Configuration> fb(fbb.Release());
      ExpectMergedOutput(fb, out);
    }
    ExpectMergedOutput(
        MergeFlatBuffers<Configuration>(&fb1.message(), &fb2.message()), out);
    ExpectMergedOutput(MergeFlatBuffers<Configuration>(fb1, fb2), out);

    // Now, to make things extra exciting, nest a config inside a config.  And
    // run all the tests.  This will exercise some fun nested merges and copies.

    {
      // in1_nested merged with "" => in1.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(fb1_nested, empty);
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
    }

    {
      // in2_nested merged with "" => in2_nested.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(fb2_nested, empty);
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in2_nested, FlatbufferToJson(fb_merged));
    }

    {
      // "" merged with in1_nested => in1_nested.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(empty, fb1_nested);
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
    }

    {
      // "" merged with in2_nested => in2_nested.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(empty, fb2_nested);
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in2_nested, FlatbufferToJson(fb_merged));
    }

    {
      // nullptr merged with in1_nested => in1_nested.
      FlatbufferDetachedBuffer<Configuration> fb_merged =
          MergeFlatBuffers<Configuration>(nullptr, &fb1_nested.message());
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
    }

    {
      // nullptr merged with in1_nested => in1_nested.
      FlatbufferDetachedBuffer<Configuration> fb_merged(
          MergeFlatBuffers<Configuration>(&fb1_nested.message(), nullptr));
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
    }

    {
      // in1_nested merged with in2_nested => out_nested.
      FlatbufferDetachedBuffer<Configuration> fb_merged(
          MergeFlatBuffers<Configuration>(fb1_nested, fb2_nested));
      ASSERT_NE(fb_merged.span().size(), 0u);

      EXPECT_EQ(out_nested, FlatbufferToJson(fb_merged));
    }

    // TODO(austin): Try more flatbuffers...
    // Now try copying various flatbuffers and confirming they match.
    {
      flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
      aos_flatbuffer_copy_fbb.ForceDefaults(true);

      LOG(INFO) << "Copying " << in1 << " "
                << absl::BytesToHexString(FromFbb(fb1)) << " at "
                << reinterpret_cast<const void *>(fb1.span().data()) << " size "
                << fb1.span().size();
      aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
          &fb1.message(), &aos_flatbuffer_copy_fbb));

      const aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
          aos_flatbuffer_copy_fbb.Release());
      ASSERT_NE(fb_copy.span().size(), 0u);

      EXPECT_TRUE(fb1.Verify());

      ASSERT_TRUE(fb_copy.Verify()) << in1;

      EXPECT_EQ(in1, FlatbufferToJson(fb_copy));
    }

    {
      flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
      aos_flatbuffer_copy_fbb.ForceDefaults(false);

      LOG(INFO) << "Copying without defaults " << in1 << " "
                << absl::BytesToHexString(FromFbb(fb1)) << " at "
                << reinterpret_cast<const void *>(fb1.span().data()) << " size "
                << fb1.span().size();
      aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
          &fb1.message(), &aos_flatbuffer_copy_fbb));

      const aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
          aos_flatbuffer_copy_fbb.Release());
      ASSERT_NE(fb_copy.span().size(), 0u);

      EXPECT_TRUE(fb1.Verify());

      ASSERT_TRUE(fb_copy.Verify()) << in1;

      EXPECT_EQ(in1, FlatbufferToJson(fb_copy));
    }

    {
      flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_message_ptr_fbb;
      aos_flatbuffer_copy_message_ptr_fbb.ForceDefaults(true);

      aos_flatbuffer_copy_message_ptr_fbb.Finish(CopyFlatBuffer<Configuration>(
          &fb2.message(), &aos_flatbuffer_copy_message_ptr_fbb));

      aos::FlatbufferDetachedBuffer<Configuration> fb_copy_message_ptr(
          aos_flatbuffer_copy_message_ptr_fbb.Release());
      ASSERT_NE(fb_copy_message_ptr.span().size(), 0u);

      flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_full_fbb;
      aos_flatbuffer_copy_full_fbb.ForceDefaults(true);

      aos_flatbuffer_copy_full_fbb.Finish(BlindCopyFlatBuffer<Configuration>(
          aos::FlatbufferSpan<Configuration>(fb2.span()),
          &aos_flatbuffer_copy_full_fbb));

      aos::FlatbufferDetachedBuffer<Configuration> fb_copy_full(
          aos_flatbuffer_copy_full_fbb.Release());
      ASSERT_NE(fb_copy_full.span().size(), 0u);

      EXPECT_TRUE(fb2.Verify());

      LOG(INFO) << "Verifying copy of " << in2;
      ASSERT_TRUE(fb_copy_message_ptr.Verify()) << in2;
      LOG(INFO) << "Verifying full of " << in2;
      ASSERT_TRUE(fb_copy_full.Verify()) << in2;

      EXPECT_EQ(in2, FlatbufferToJson(fb_copy_message_ptr));
      EXPECT_EQ(in2, FlatbufferToJson(fb_copy_full));
    }

    {
      flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
      aos_flatbuffer_copy_fbb.ForceDefaults(true);

      aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
          &fb1_nested.message(), &aos_flatbuffer_copy_fbb));

      aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
          aos_flatbuffer_copy_fbb.Release());
      ASSERT_NE(fb_copy.span().size(), 0u);

      ASSERT_TRUE(fb_copy.Verify());

      EXPECT_EQ(in1_nested, FlatbufferToJson(fb_copy));
    }

    {
      flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
      aos_flatbuffer_copy_fbb.ForceDefaults(true);

      aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
          &fb2_nested.message(), &aos_flatbuffer_copy_fbb));

      aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
          aos_flatbuffer_copy_fbb.Release());
      ASSERT_NE(fb_copy.span().size(), 0u);

      ASSERT_TRUE(fb_copy.Verify());

      EXPECT_EQ(in2_nested, FlatbufferToJson(fb_copy));
    }
  }
};

// Test the easy ones.  Test every type, single, no nesting.
TEST_F(FlatbufferMerge, Basic) {
  JsonMerge("{  }", "{  }", "{  }");

  JsonMerge("{ \"foo_bool\": true }", "{ \"foo_bool\": false }",
            "{ \"foo_bool\": false }");

  JsonMerge("{ \"foo_bool\": false }", "{ \"foo_bool\": true }",
            "{ \"foo_bool\": true }");

  JsonMerge("{ \"foo_byte\": 5 }", "{ \"foo_byte\": -7 }",
            "{ \"foo_byte\": -7 }");

  JsonMerge("{ \"foo_ubyte\": 5 }", "{ \"foo_ubyte\": 7 }",
            "{ \"foo_ubyte\": 7 }");

  JsonMerge("{ \"foo_short\": 5 }", "{ \"foo_short\": 7 }",
            "{ \"foo_short\": 7 }");

  JsonMerge("{ \"foo_int\": 5 }", "{ \"foo_int\": 7 }", "{ \"foo_int\": 7 }");

  JsonMerge("{ \"foo_uint\": 5 }", "{ \"foo_uint\": 7 }",
            "{ \"foo_uint\": 7 }");

  JsonMerge("{ \"foo_long\": 5 }", "{ \"foo_long\": 7 }",
            "{ \"foo_long\": 7 }");

  JsonMerge("{ \"foo_ulong\": 5 }", "{ \"foo_ulong\": 7 }",
            "{ \"foo_ulong\": 7 }");

  JsonMerge("{ \"foo_float\": 5 }", "{ \"foo_float\": 7.1 }",
            "{ \"foo_float\": 7.1 }");

  JsonMerge("{ \"foo_double\": 5 }", "{ \"foo_double\": 7.1 }",
            "{ \"foo_double\": 7.1 }");
}

// Test arrays of simple types.
TEST_F(FlatbufferMerge, Array) {
  JsonMerge("{ \"foo_string\": \"baz\" }", "{ \"foo_string\": \"bar\" }",
            "{ \"foo_string\": \"bar\" }");

  JsonMerge("{ \"vector_foo_bool\": [ true, true, false ] }",
            "{ \"vector_foo_bool\": [ false, true, true, false ] }",
            "{ \"vector_foo_bool\": [ true, true, false, false, "
            "true, true, false ] }");

  JsonMerge("{ \"vector_foo_byte\": [ 9, 7, 1 ] }",
            "{ \"vector_foo_byte\": [ -3, 1, 3, 2 ] }",
            "{ \"vector_foo_byte\": [ 9, 7, 1, -3, 1, 3, 2 ] }");

  JsonMerge("{ \"vector_foo_ubyte\": [ 9, 7, 1 ] }",
            "{ \"vector_foo_ubyte\": [ 3, 1, 3, 2 ] }",
            "{ \"vector_foo_ubyte\": [ 9, 7, 1, 3, 1, 3, 2 ] }");

  JsonMerge("{ \"vector_foo_short\": [ 9, 7, 1 ] }",
            "{ \"vector_foo_short\": [ -3, 1, 3, 2 ] }",
            "{ \"vector_foo_short\": [ 9, 7, 1, -3, 1, 3, 2 ] }");

  JsonMerge("{ \"vector_foo_ushort\": [ 9, 7, 1 ] }",
            "{ \"vector_foo_ushort\": [ 3, 1, 3, 2 ] }",
            "{ \"vector_foo_ushort\": [ 9, 7, 1, 3, 1, 3, 2 ] }");

  JsonMerge("{ \"vector_foo_int\": [ 9, 7, 1 ] }",
            "{ \"vector_foo_int\": [ -3, 1, 3, 2 ] }",
            "{ \"vector_foo_int\": [ 9, 7, 1, -3, 1, 3, 2 ] }");

  JsonMerge("{ \"vector_foo_uint\": [ 9, 7, 1 ] }",
            "{ \"vector_foo_uint\": [ 3, 1, 3, 2 ] }",
            "{ \"vector_foo_uint\": [ 9, 7, 1, 3, 1, 3, 2 ] }");

  JsonMerge("{ \"vector_foo_long\": [ 9, 7, 1 ] }",
            "{ \"vector_foo_long\": [ -3, 1, 3, 2 ] }",
            "{ \"vector_foo_long\": [ 9, 7, 1, -3, 1, 3, 2 ] }");

  JsonMerge("{ \"vector_foo_ulong\": [ 9, 7, 1 ] }",
            "{ \"vector_foo_ulong\": [ 3, 1, 3, 2 ] }",
            "{ \"vector_foo_ulong\": [ 9, 7, 1, 3, 1, 3, 2 ] }");

  JsonMerge("{ \"vector_foo_float\": [ 9, 7, 1 ] }",
            "{ \"vector_foo_float\": [ -3, 1.3, 3, 2 ] }",
            "{ \"vector_foo_float\": [ 9, 7, 1, -3, 1.3, 3, 2 ] }");

  JsonMerge(
      "{ \"vector_foo_string\": [ \"9\", \"7\", \"1 \" ] }",
      "{ \"vector_foo_string\": [ \"31\", \"32\" ] }",
      "{ \"vector_foo_string\": [ \"9\", \"7\", \"1 \", \"31\", \"32\" ] }");
}

// Test nested messages, and arrays of nested messages.
TEST_F(FlatbufferMerge, NestedStruct) {
  JsonMerge(
      "{ \"single_application\": { \"name\": \"woot\" } }",
      "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
      "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }");

  JsonMerge(
      "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
      "{ \"single_application\": { \"name\": \"woot\" } }",
      "{ \"single_application\": { \"name\": \"woot\", \"priority\": 7 } }");

  JsonMerge("{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] }",
            "{ \"apps\": [ { \"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }",
            "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" }, { "
            "\"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }");
}

// Test nested messages, and arrays of nested messages.
TEST(FlatbufferCopy, WholesaleCopy) {
  flatbuffers::FlatBufferBuilder fbb_expected;
  fbb_expected.ForceDefaults(true);
  fbb_expected.DedupVtables(false);

  {
    flatbuffers::Offset<flatbuffers::String> name1_offset =
        fbb_expected.CreateString("wow");

    std::vector<flatbuffers::Offset<Application>> application_offsets;
    Application::Builder a1_builder(fbb_expected);
    a1_builder.add_name(name1_offset);
    a1_builder.add_priority(7);
    a1_builder.add_long_thingy(0x2549713132LL);
    application_offsets.emplace_back(a1_builder.Finish());

    flatbuffers::Offset<flatbuffers::String> name2_offset =
        fbb_expected.CreateString("foo");
    Application::Builder a2_builder(fbb_expected);
    a2_builder.add_name(name2_offset);
    a2_builder.add_priority(3);
    a2_builder.add_long_thingy(9);
    application_offsets.emplace_back(a2_builder.Finish());

    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
        applications_offset = fbb_expected.CreateVector(application_offsets);

    Configuration::Builder configuration_builder(fbb_expected);
    configuration_builder.add_apps(applications_offset);
    fbb_expected.Finish(configuration_builder.Finish());
  }

  LOG(INFO) << "Initial alignment " << fbb_expected.GetBufferMinAlignment();

  aos::FlatbufferDetachedBuffer<Configuration> expected(fbb_expected.Release());

  LOG(INFO) << "Expected "
            << absl::BytesToHexString(std::string_view(
                   reinterpret_cast<char *>(expected.span().data()),
                   expected.span().size()));

  aos::FlatbufferDetachedBuffer<Application> a1 = []() {
    flatbuffers::FlatBufferBuilder fbb;
    fbb.ForceDefaults(true);

    flatbuffers::Offset<flatbuffers::String> name1_offset =
        fbb.CreateString("wow");

    Application::Builder a1_builder(fbb);
    a1_builder.add_name(name1_offset);
    a1_builder.add_priority(7);
    a1_builder.add_long_thingy(0x2549713132LL);
    flatbuffers::Offset<Application> a1 = a1_builder.Finish();

    fbb.Finish(a1);
    return fbb.Release();
  }();

  aos::FlatbufferDetachedBuffer<Application> a2 =
      JsonToFlatbuffer<Application>(static_cast<const char *>(
          "{ \"name\": \"foo\", \"priority\": 3, \"long_thingy\": 9 }"));

  aos::FlatbufferDetachedBuffer<Configuration> c1 = [&a1, &a2]() {
    flatbuffers::FlatBufferBuilder fbb;
    fbb.ForceDefaults(true);

    std::vector<flatbuffers::Offset<Application>> application_offsets;
    application_offsets.emplace_back(BlindCopyFlatBuffer(a1, &fbb));
    application_offsets.emplace_back(BlindCopyFlatBuffer(a2, &fbb));

    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
        applications_offset = fbb.CreateVector(application_offsets);

    Configuration::Builder configuration_builder(fbb);
    configuration_builder.add_apps(applications_offset);
    fbb.Finish(configuration_builder.Finish());

    return fbb.Release();
  }();

  LOG(INFO) << "Got      "
            << absl::BytesToHexString(
                   std::string_view(reinterpret_cast<char *>(c1.span().data()),
                                    c1.span().size()));

  aos::FlatbufferDetachedBuffer<Configuration> c2 = [&a1, &a2]() {
    flatbuffers::FlatBufferBuilder fbb;
    fbb.ForceDefaults(true);

    std::vector<flatbuffers::Offset<Application>> application_offsets;
    application_offsets.emplace_back(CopyFlatBuffer(&a1.message(), &fbb));
    application_offsets.emplace_back(CopyFlatBuffer(&a2.message(), &fbb));

    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
        applications_offset = fbb.CreateVector(application_offsets);

    Configuration::Builder configuration_builder(fbb);
    configuration_builder.add_apps(applications_offset);
    fbb.Finish(configuration_builder.Finish());

    return fbb.Release();
  }();

  LOG(INFO) << "Got      "
            << absl::BytesToHexString(
                   std::string_view(reinterpret_cast<char *>(c2.span().data()),
                                    c2.span().size()));

  ASSERT_TRUE(expected.Verify());
  ASSERT_TRUE(c1.Verify());
  ASSERT_TRUE(c2.Verify());

  LOG(INFO) << FlatbufferToJson(expected);
  LOG(INFO) << FlatbufferToJson(c1);
  LOG(INFO) << FlatbufferToJson(c2);
  EXPECT_EQ(FlatbufferToJson(expected), FlatbufferToJson(c1));
  EXPECT_EQ(FlatbufferToJson(expected), FlatbufferToJson(c2));
}

// Tests a compare of 2 basic (different) messages.
TEST_F(FlatbufferMerge, CompareDifferent) {
  aos::FlatbufferDetachedBuffer<Configuration> message1(JsonToFlatbuffer(
      "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
      ConfigurationTypeTable()));
  aos::FlatbufferDetachedBuffer<Configuration> message2(JsonToFlatbuffer(
      "{ \"single_application\": { \"name\": \"wow\", \"priority\": 8 } }",
      ConfigurationTypeTable()));

  EXPECT_FALSE(CompareFlatBuffer(&message1.message(), &message2.message()));
}

// TODO(austin): enums
// TODO(austin): unions
// TODO(austin): struct

}  // namespace aos::testing
