// WARNING: This file is machine generated by fidlgen.

#include <fidl/test/protocolrequest/cpp/libfuzzer.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/cpp/fuzzing/fuzzer.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/zx/channel.h>
#include <zircon/errors.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

using namespace ::fuzzing;
using namespace ::fidl::test::protocolrequest;

// Add //build/fuzzing:fuzzing_verbose_logging to a GN target's configs to
// enable.
#if FUZZING_VERBOSE_LOGGING
#include <stdio.h>
#define xprintf(fmt...) printf(fmt)
#else
#define xprintf(fmt...) \
  do {                  \
  } while (0)
#endif

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data_, size_t size_) {
  static ::async::Loop* loop_ = nullptr;

  if (loop_ == nullptr) {
    xprintf("Starting client async loop\n");
    loop_ = new ::async::Loop(&kAsyncLoopConfigAttachToCurrentThread);
  }

  // Must fuzz some protocol; first two bytes used to select protocol and
  // method.
  if (size_ < 2) {
    xprintf("Early exit: Input too small: %zu\n", size_);
    return 0;
  }
  size_ -= 2;

  uint8_t protocol_selector_ = data_[0];
  uint8_t protocol_selection_ = protocol_selector_ % 2;

  xprintf("Starting fuzzer with %zu bytes of data\n", size_);

  // Hardcode mutually-exclusive if blocks that selects exactly one protocol.
  [[maybe_unused]] zx_status_t status_;
  if (protocol_selection_ == 0) {
#if !defined(PROTOCOL_fidl_test_protocolrequest_Parent)
    // Selected protocol from FIDL file that is not part of this fuzzer.
    xprintf(
        "Early exit: Chose disabled protocol: "
        "fidl_test_protocolrequest_Parent\n");
    return 0;
#else

    ::fidl::InterfacePtr< ::fidl::test::protocolrequest::Parent> protocol_;

    xprintf("Starting fidl_test_protocolrequest_Parent service\n");
    ::fidl::fuzzing::Fuzzer< ::fidl::test::protocolrequest::Parent> fuzzer_(
        loop_->dispatcher());
    if ((status_ = fuzzer_.Init()) != ZX_OK) {
      xprintf("Early exit: fuzzer.Init returned bad status: %d\n", status_);
      return 0;
    }

    if ((status_ = fuzzer_.BindService()) != ZX_OK) {
      xprintf("Early exit: fuzzer.BindService returned bad status: %d\n",
              status_);
      return 0;
    }

    if ((status_ = fuzzer_.BindClient(&protocol_, loop_->dispatcher())) !=
        ZX_OK) {
      xprintf("Early exit: fuzzer.BindClient returned bad status: %d\n",
              status_);
      return 0;
    }

    FuzzInput src_(data_, size_);

    uint8_t method_selector_ = data_[1];
    uint8_t method_selection_ = method_selector_ % 4;
    if (method_selection_ == 2) {
#if !(ALL_METHODS || defined(METHOD_TakeChild))
      // Selected method from protocol that is not part of this fuzzer.
      xprintf("Early exit: Chose disabled method: TakeChild\n");
      return 0;
#else
      const size_t min_size_ = MinSize<
          ::fidl::InterfaceHandle< ::fidl::test::protocolrequest::Child> >();

      // Must have enough bytes for input.
      if (size_ < min_size_) {
        xprintf("Early exit: Input size too small: %zu < %zu\n", size_,
                min_size_);
        return 0;
      }

      const size_t slack_size_ = size_ - min_size_;
      const size_t slack_size_per_param = slack_size_ / 1;

      xprintf("Allocating parameters with %zu bytes (%zu bytes each)\n",
              slack_size_, slack_size_per_param);

      size_t param_size_;
      param_size_ = MinSize< ::fidl::InterfaceHandle<
                        ::fidl::test::protocolrequest::Child> >() +
                    slack_size_per_param;
      xprintf(
          "Allocating %zu bytes for "
          "::fidl::InterfaceHandle<::fidl::test::protocolrequest::Child> c\n",
          param_size_);
      ::fidl::InterfaceHandle< ::fidl::test::protocolrequest::Child> c =
          Allocate< ::fidl::InterfaceHandle<
              ::fidl::test::protocolrequest::Child> >{}(&src_, &param_size_);

      xprintf("Invoking method fidl_test_protocolrequest_Parent.TakeChild\n");
      protocol_->TakeChild(std::move(c));
#endif
    }
    if (method_selection_ == 3) {
#if !(ALL_METHODS || defined(METHOD_TakeChildRequest))
      // Selected method from protocol that is not part of this fuzzer.
      xprintf("Early exit: Chose disabled method: TakeChildRequest\n");
      return 0;
#else
      const size_t min_size_ = MinSize<
          ::fidl::InterfaceRequest< ::fidl::test::protocolrequest::Child> >();

      // Must have enough bytes for input.
      if (size_ < min_size_) {
        xprintf("Early exit: Input size too small: %zu < %zu\n", size_,
                min_size_);
        return 0;
      }

      const size_t slack_size_ = size_ - min_size_;
      const size_t slack_size_per_param = slack_size_ / 1;

      xprintf("Allocating parameters with %zu bytes (%zu bytes each)\n",
              slack_size_, slack_size_per_param);

      size_t param_size_;
      param_size_ = MinSize< ::fidl::InterfaceRequest<
                        ::fidl::test::protocolrequest::Child> >() +
                    slack_size_per_param;
      xprintf(
          "Allocating %zu bytes for "
          "::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child> r\n",
          param_size_);
      ::fidl::InterfaceRequest< ::fidl::test::protocolrequest::Child> r =
          Allocate< ::fidl::InterfaceRequest<
              ::fidl::test::protocolrequest::Child> >{}(&src_, &param_size_);

      xprintf(
          "Invoking method "
          "fidl_test_protocolrequest_Parent.TakeChildRequest\n");
      protocol_->TakeChildRequest(std::move(r));
#endif
    }

    loop_->RunUntilIdle();

    if ((status_ = fuzzer_.WaitForCallback()) != ZX_OK) {
      xprintf("fuzzer.WaitForCallback returned bad status: %d\n", status_);
    }

    protocol_.Unbind();
#endif
  }

  xprintf("Fuzzer stopped!\n");

  return 0;
}
