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

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

// 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.
  zx_status_t status_;
  if (protocol_selection_ == 0) {
#if !defined(PROTOCOL_fidl_test_requestflexibleenvelope_Protocol)
    // Selected protocol from FIDL file that is not part of this fuzzer.
    xprintf(
        "Early exit: Chose disabled protocol: "
        "fidl_test_requestflexibleenvelope_Protocol\n");
    return 0;
#else

    ::fidl::InterfacePtr< ::fidl::test::requestflexibleenvelope::Protocol>
        protocol_;

    xprintf("Starting fidl_test_requestflexibleenvelope_Protocol service\n");
    ::fidl::fuzzing::Fuzzer< ::fidl::test::requestflexibleenvelope::Protocol>
        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_ % 2;
    if (method_selection_ == 0) {
#if !(ALL_METHODS || defined(METHOD_RequestStrictResponseFlexible))
      // Selected method from protocol that is not part of this fuzzer.
      xprintf(
          "Early exit: Chose disabled method: RequestStrictResponseFlexible\n");
      return 0;
#else
      const size_t min_size_ = MinSize<StrictFoo>();

      // 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<StrictFoo>() + slack_size_per_param;
      xprintf("Allocating %zu bytes for StrictFoo s\n", param_size_);
      StrictFoo s = Allocate<StrictFoo>{}(&src_, &param_size_);

      xprintf(
          "Invoking method "
          "fidl_test_requestflexibleenvelope_Protocol."
          "RequestStrictResponseFlexible\n");
      protocol_->RequestStrictResponseFlexible(
          std::move(s),
          [signaller = fuzzer_.NewCallbackSignaller()](FlexibleFoo f) {
            xprintf(
                "Invoked "
                "fidl_test_requestflexibleenvelope_Protocol."
                "RequestStrictResponseFlexible\n");
            zx_status_t status_ = signaller.SignalCallback();
            if (status_ != ZX_OK) {
              xprintf("signaller.SignalCallback returned bad status: %d\n",
                      status_);
            }
          });
#endif
    }
    if (method_selection_ == 1) {
#if !(ALL_METHODS || defined(METHOD_RequestFlexibleResponseStrict))
      // Selected method from protocol that is not part of this fuzzer.
      xprintf(
          "Early exit: Chose disabled method: RequestFlexibleResponseStrict\n");
      return 0;
#else
      const size_t min_size_ = MinSize<FlexibleFoo>();

      // 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<FlexibleFoo>() + slack_size_per_param;
      xprintf("Allocating %zu bytes for FlexibleFoo s\n", param_size_);
      FlexibleFoo s = Allocate<FlexibleFoo>{}(&src_, &param_size_);

      xprintf(
          "Invoking method "
          "fidl_test_requestflexibleenvelope_Protocol."
          "RequestFlexibleResponseStrict\n");
      protocol_->RequestFlexibleResponseStrict(
          std::move(s),
          [signaller = fuzzer_.NewCallbackSignaller()](StrictFoo f) {
            xprintf(
                "Invoked "
                "fidl_test_requestflexibleenvelope_Protocol."
                "RequestFlexibleResponseStrict\n");
            zx_status_t status_ = signaller.SignalCallback();
            if (status_ != ZX_OK) {
              xprintf("signaller.SignalCallback returned bad status: %d\n",
                      status_);
            }
          });
#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;
}
