#include "test_builder.h"

#include "flatbuffers/stl_emulation.h"
#include "monster_test_generated.h"

using namespace MyGame::Example;

struct OwnedAllocator : public flatbuffers::DefaultAllocator {};

class TestHeapBuilder : public flatbuffers::FlatBufferBuilder {
 private:
  TestHeapBuilder(const TestHeapBuilder &);
  TestHeapBuilder &operator=(const TestHeapBuilder &);

 public:
  TestHeapBuilder()
      : flatbuffers::FlatBufferBuilder(2048, new OwnedAllocator(), true) {}

  TestHeapBuilder(TestHeapBuilder &&other)
      : FlatBufferBuilder(std::move(other)) {}

  TestHeapBuilder &operator=(TestHeapBuilder &&other) {
    FlatBufferBuilder::operator=(std::move(other));
    return *this;
  }
};

// This class simulates flatbuffers::grpc::detail::SliceAllocatorMember
struct AllocatorMember {
  flatbuffers::DefaultAllocator member_allocator_;
};

struct GrpcLikeMessageBuilder : private AllocatorMember,
                                public flatbuffers::FlatBufferBuilder {
 private:
  GrpcLikeMessageBuilder(const GrpcLikeMessageBuilder &);
  GrpcLikeMessageBuilder &operator=(const GrpcLikeMessageBuilder &);

 public:
  GrpcLikeMessageBuilder()
      : flatbuffers::FlatBufferBuilder(1024, &member_allocator_, false) {}

  GrpcLikeMessageBuilder(GrpcLikeMessageBuilder &&other)
      : FlatBufferBuilder(1024, &member_allocator_, false) {
    // Default construct and swap idiom.
    Swap(other);
  }

  GrpcLikeMessageBuilder &operator=(GrpcLikeMessageBuilder &&other) {
    // Construct temporary and swap idiom
    GrpcLikeMessageBuilder temp(std::move(other));
    Swap(temp);
    return *this;
  }

  void Swap(GrpcLikeMessageBuilder &other) {
    // No need to swap member_allocator_ because it's stateless.
    FlatBufferBuilder::Swap(other);
    // After swapping the FlatBufferBuilder, we swap back the allocator, which
    // restores the original allocator back in place. This is necessary because
    // MessageBuilder's allocator is its own member (SliceAllocatorMember). The
    // allocator passed to FlatBufferBuilder::vector_downward must point to this
    // member.
    buf_.swap_allocator(other.buf_);
  }
};

flatbuffers::Offset<Monster> populate1(
    flatbuffers::FlatBufferBuilder &builder) {
  auto name_offset = builder.CreateString(m1_name());
  return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color());
}

flatbuffers::Offset<Monster> populate2(
    flatbuffers::FlatBufferBuilder &builder) {
  auto name_offset = builder.CreateString(m2_name());
  return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color());
}

uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size,
                          size_t &offset) {
  return fbb.ReleaseRaw(size, offset);
}

void free_raw(flatbuffers::grpc::MessageBuilder &, uint8_t *) {
  // release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument
  // MessageBuilder. It's semantically wrong as MessageBuilder has its own
  // ReleaseRaw member function that takes three arguments. In such cases
  // though, ~MessageBuilder() invokes ~SliceAllocator() that takes care of
  // deleting memory as it calls grpc_slice_unref. Obviously, this behavior is
  // very surprising as the pointer returned by FlatBufferBuilder::ReleaseRaw is
  // not valid as soon as MessageBuilder goes out of scope. This problem does
  // not occur with FlatBufferBuilder.
}

void free_raw(flatbuffers::FlatBufferBuilder &, uint8_t *buf) {
  flatbuffers::DefaultAllocator().deallocate(buf, 0);
}

bool verify(const flatbuffers::DetachedBuffer &buf,
            const std::string &expected_name, Color color) {
  const Monster *monster = flatbuffers::GetRoot<Monster>(buf.data());
  return (monster->name()->str() == expected_name) &&
         (monster->color() == color);
}

bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name,
            Color color) {
  const Monster *monster = flatbuffers::GetRoot<Monster>(buf + offset);
  return (monster->name()->str() == expected_name) &&
         (monster->color() == color);
}

bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb,
                      const std::string &expected_name, Color color) {
  flatbuffers::DetachedBuffer buf = fbb.Release();
  return verify(buf, expected_name, color);
}

// forward-declared in test.cpp
void FlatBufferBuilderTest();

void FlatBufferBuilderTest() {
  using flatbuffers::FlatBufferBuilder;

  BuilderTests<FlatBufferBuilder>::all_tests();
  BuilderTests<TestHeapBuilder>::all_tests();
  BuilderTests<GrpcLikeMessageBuilder>::all_tests();

  BuilderReuseTestSelector tests[4] = {
    REUSABLE_AFTER_RELEASE, REUSABLE_AFTER_RELEASE_RAW,
    REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN,
    REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
  };

  BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(
      TestSelector(tests, tests + 4));
  BuilderReuseTests<TestHeapBuilder, TestHeapBuilder>::run_tests(
      TestSelector(tests, tests + 4));
  BuilderReuseTests<GrpcLikeMessageBuilder, GrpcLikeMessageBuilder>::run_tests(
      TestSelector(tests, tests + 4));
}

// forward-declared in test_builder.h
void CheckTestGeneratedIsValid(const MyGame::Example::Color&);

// Link-time check using pointer type.
void CheckTestGeneratedIsValid(const MyGame::Example::Color &) {}
