#include <lib/fidl/internal.h>

#include <iostream>

#include <gtest/gtest.h>

#include "lib/fidl/cpp/clone.h"

namespace fidl {
namespace test {
namespace util {

bool cmp_payload(const uint8_t* actual, size_t actual_size, const uint8_t* expected,
                 size_t expected_size);

class EncoderFactoryV1 {
 public:
  static Encoder makeEncoder() {
    Encoder enc(0xfefefefe);
    return enc;
  }
};

template <class T, class Callback>
void WithCodingTableFor(const fidl::Encoder& enc, Callback callback) {
  const size_t encoded_size = fidl::CodingTraits<T>::inline_size_v1_no_ee;
  const size_t padding_size = FIDL_ALIGN(encoded_size) - encoded_size;

  const FidlStructField fake_interface_fields[] = {
      FidlStructField(T::FidlType, sizeof(fidl_message_header_t), padding_size),
  };

  const FidlCodedStruct fake_interface_struct = {
      .tag = kFidlTypeStruct,
      .field_count = 1,
      .size = static_cast<uint32_t>(sizeof(fidl_message_header_t) + encoded_size),
      .fields = fake_interface_fields,
      .name = "Input",
  };

  callback(encoded_size, &fake_interface_struct);
}

template <class Output, class Input>
Output RoundTrip(const Input& input) {
  fidl::Encoder enc(0xfefefefe);
  const char* err_msg = nullptr;
  Output output;

  WithCodingTableFor<Input>(enc, [&](size_t encoded_size, const fidl_type_t* type) {
    auto ofs = enc.Alloc(encoded_size);
    fidl::Clone(input).Encode(&enc, ofs);
    auto msg = enc.GetMessage();
    EXPECT_EQ(ZX_OK, msg.Validate(type, &err_msg)) << err_msg;

    WithCodingTableFor<Output>(enc, [&](size_t encoded_size, const fidl_type_t* type) {
      EXPECT_EQ(ZX_OK, msg.Decode(type, &err_msg)) << err_msg;
      fidl::Decoder dec(std::move(msg));
      Output::Decode(&dec, &output, ofs);
    });
  });

  return output;
}

template <class Output>
Output DecodedBytes(std::vector<uint8_t> input) {
  // Create a fake coded type for the input object with added header.
  FidlStructField fields_v1[] = {
      FidlStructField(Output::FidlType, sizeof(fidl_message_header_t), 0u)};
  assert(Output::FidlType->type_tag() == kFidlTypeStruct);
  FidlCodedStruct obj_with_header_v1 = {
      .tag = kFidlTypeStruct,
      .field_count = 1u,
      .size = static_cast<uint32_t>(sizeof(fidl_message_header_t) +
                                    FIDL_ALIGN(Output::FidlType->coded_struct().size)),
      .fields = fields_v1,
      .name = "",
  };
  Message message(BytePart(input.data(), input.capacity(), input.size()), HandlePart());

  const char* error = nullptr;
  EXPECT_EQ(ZX_OK, message.Decode(&obj_with_header_v1, &error)) << error;

  fidl::Decoder decoder(std::move(message));
  Output output;
  Output::Decode(&decoder, &output, sizeof(fidl_message_header_t));

  return output;
}

template <class Input, class EncoderFactory = EncoderFactoryV1>
bool ValueToBytes(const Input& input, const std::vector<uint8_t>& expected) {
  auto enc = EncoderFactory::makeEncoder();
  auto offset = enc.Alloc(EncodingInlineSize<Input, fidl::Encoder>(&enc));
  fidl::Clone(input).Encode(&enc, offset);
  auto msg = enc.GetMessage();
  auto payload = msg.payload();
  return cmp_payload(reinterpret_cast<const uint8_t*>(payload.data()), payload.actual(),
                     reinterpret_cast<const uint8_t*>(expected.data()), expected.size());
}

template <class Output>
void CheckDecodeFailure(std::vector<uint8_t> input, const zx_status_t expected_failure_code) {
  Message message(BytePart(input.data(), input.capacity(), input.size()), HandlePart());

  const char* error = nullptr;
  EXPECT_EQ(expected_failure_code, message.Decode(Output::FidlType, &error)) << error;
}

template <class Input, class EncoderFactory = EncoderFactoryV1>
void CheckEncodeFailure(const Input& input, const zx_status_t expected_failure_code) {
  auto enc = EncoderFactory::makeEncoder();
  auto offset = enc.Alloc(EncodingInlineSize<Input, fidl::Encoder>(&enc));
  fidl::Clone(input).Encode(&enc, offset);
  auto msg = enc.GetMessage();
  const char* error = nullptr;
  EXPECT_EQ(expected_failure_code, msg.Validate(Input::FidlType, &error)) << error;
}

}  // namespace util
}  // namespace test
}  // namespace fidl
