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

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

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

    ::fidl::InterfacePtr< ::fidl::test::inheritance::super> protocol_;

    xprintf("Starting fidl_test_inheritance_super service\n");
    ::fidl::fuzzing::Fuzzer< ::fidl::test::inheritance::super> 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;
    if (method_selection_ == 0) {
#if !(ALL_METHODS || defined(METHOD_foo))
      // Selected method from protocol that is not part of this fuzzer.
      xprintf("Early exit: Chose disabled method: foo\n");
      return 0;
#else
      const size_t min_size_ = MinSize< ::std::string>();

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

      xprintf("Invoking method fidl_test_inheritance_super.foo\n");
      protocol_->foo(std::move(s), [signaller = fuzzer_.NewCallbackSignaller()](
                                       int64_t y) {
        xprintf("Invoked fidl_test_inheritance_super.foo\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
  }
  if (protocol_selection_ == 1) {
#if !defined(PROTOCOL_fidl_test_inheritance_sub)
    // Selected protocol from FIDL file that is not part of this fuzzer.
    xprintf("Early exit: Chose disabled protocol: fidl_test_inheritance_sub\n");
    return 0;
#else

    ::fidl::InterfacePtr< ::fidl::test::inheritance::sub> protocol_;

    xprintf("Starting fidl_test_inheritance_sub service\n");
    ::fidl::fuzzing::Fuzzer< ::fidl::test::inheritance::sub> 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;
    if (method_selection_ == 0) {
#if !(ALL_METHODS || defined(METHOD_foo))
      // Selected method from protocol that is not part of this fuzzer.
      xprintf("Early exit: Chose disabled method: foo\n");
      return 0;
#else
      const size_t min_size_ = MinSize< ::std::string>();

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

      xprintf("Invoking method fidl_test_inheritance_sub.foo\n");
      protocol_->foo(std::move(s), [signaller = fuzzer_.NewCallbackSignaller()](
                                       int64_t y) {
        xprintf("Invoked fidl_test_inheritance_sub.foo\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;
}
