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

#include <fidl/test/foreigntypeinresponseusedthroughcompose/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::foreigntypeinresponseusedthroughcompose;

// 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_ % 1;

  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_foreigntypeinresponseusedthroughcompose_Top)
    // Selected protocol from FIDL file that is not part of this fuzzer.
    xprintf(
        "Early exit: Chose disabled protocol: "
        "fidl_test_foreigntypeinresponseusedthroughcompose_Top\n");
    return 0;
#else

    ::fidl::InterfacePtr<
        ::fidl::test::foreigntypeinresponseusedthroughcompose::Top>
        protocol_;

    xprintf(
        "Starting fidl_test_foreigntypeinresponseusedthroughcompose_Top "
        "service\n");
    ::fidl::fuzzing::Fuzzer<
        ::fidl::test::foreigntypeinresponseusedthroughcompose::Top>
        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_ % 1;

    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;
}
