// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIB_FIDL_CPP_FUZZING_FUZZER_H_
#define LIB_FIDL_CPP_FUZZING_FUZZER_H_

#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/zx/clock.h>
#include <lib/zx/event.h>
#include <lib/zx/time.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <utility>

#ifdef __cplusplus
extern "C" {
#endif

zx_status_t fuzzer_init();
zx_status_t fuzzer_connect(zx_handle_t, async_dispatcher_t*);
zx_status_t fuzzer_disconnect(zx_handle_t, async_dispatcher_t*);
zx_status_t fuzzer_clean_up();

#ifdef __cplusplus
}
#endif

namespace fidl {
namespace fuzzing {

// Helper class for signalling when a callback completes.
//
// Use `zx::unowned_event` because `Fuzzer` that owns the event may go out of scope before callback
// is invoked.
class FuzzerCallbackSignaller {
 public:
  explicit FuzzerCallbackSignaller(const zx::event& evt) : evt_(evt) {}

  // Invoked from within method callback to signal that callback has run. Note that `signal()` may
  // return non-OK status if, for example, fuzzer timed out waiting for callback.
  zx_status_t SignalCallback() const { return evt_->signal(0, ZX_USER_SIGNAL_7); }

 private:
  zx::unowned_event evt_;
};

// Helper class for code generated by the `cpp_libfuzzer` FIDL compiler backend.
//
// This class implements setup, bind, and teardown for a single pass of a fuzzer generated using the
// `cpp_libfuzzer` FIDL compiler backend. It _always_ owns `evt_` handle. It _sometimes_ owns the
// `client_handle_` and `service_handle_`; these are stored as raw handles because one of them is
// passed to an opaque service provider via a C interface.
template <typename Impl>
class Fuzzer {
 public:
  Fuzzer(async_dispatcher_t* dispatcher)
      : init_status_(ZX_ERR_UNAVAILABLE),
        service_status_(ZX_ERR_UNAVAILABLE),
        client_status_(ZX_ERR_UNAVAILABLE),
        service_handle_(ZX_HANDLE_INVALID),
        client_handle_(ZX_HANDLE_INVALID),
        dispatcher_(dispatcher) {}

  // Attempt to initialize the fuzzer by allowing the service provider to initialize itself and
  // creating kernel primitives.
  zx_status_t Init() {
    if ((init_status_ = fuzzer_init()) != ZX_OK) {
      return init_status_;
    }
    if ((init_status_ = zx_channel_create(0, &service_handle_, &client_handle_)) != ZX_OK) {
      return init_status_;
    }
    if ((init_status_ = zx::event::create(0, &evt_)) != ZX_OK) {
      return init_status_;
    }

    return init_status_;
  }

  // Attempt to pass `service_handle_` to service provider. If successful, the service
  // implementation now owns `service_handle_`.
  zx_status_t BindService() {
    service_status_ = fuzzer_connect(service_handle_, dispatcher_);
    return service_status_;
  }

  // Attempt to initialize client `InterfacePtr`. If successful, the `InterfacePtr` now owns
  // `client_handle_`.
  zx_status_t BindClient(InterfacePtr<Impl>* iface, async_dispatcher_t* dispatcher) {
    zx::channel client_channel(client_handle_);
    client_status_ = iface->Bind(std::move(client_channel), dispatcher);
    return client_status_;
  }

  // Produce a callback signaller that may outlive this Fuzzer.
  FuzzerCallbackSignaller NewCallbackSignaller() { return FuzzerCallbackSignaller(evt_); }

  // Invoked from main fuzzer thread to wait for callback to run.
  // TODO(markdittmer): Make deadline configurable.
  zx_status_t WaitForCallback() const {
    zx_signals_t pending;
    zx::time deadline = zx::clock::get_monotonic() + zx::duration(5000000000);
    return evt_.wait_one(ZX_USER_SIGNAL_7, deadline, &pending);
  }

  ~Fuzzer() {
    // Fuzzer owns client_handle_ when client setup failed.
    if (client_status_ != ZX_OK) {
      zx_handle_close(client_handle_);
    }

    // Service owns service_handle_ when service setup succeeded, else Fuzzer owns it.
    if (service_status_ == ZX_OK) {
      fuzzer_disconnect(service_handle_, dispatcher_);
    } else {
      zx_handle_close(service_handle_);
    }

    // Clean up only when init succeeded.
    if (init_status_ == ZX_OK) {
      fuzzer_clean_up();
    }
  }

 private:
  zx_status_t init_status_;
  zx_status_t service_status_;
  zx_status_t client_status_;
  zx_handle_t service_handle_;
  zx_handle_t client_handle_;
  zx::event evt_;
  async_dispatcher_t* dispatcher_;
};

}  // namespace fuzzing
}  // namespace fidl

#endif  // LIB_FIDL_CPP_FUZZING_FUZZER_H_
