// Copyright 2021 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 SRC_DEVICES_BIN_DRIVER_RUNTIME_RUNTIME_TEST_CASE_H_
#define SRC_DEVICES_BIN_DRIVER_RUNTIME_RUNTIME_TEST_CASE_H_

#include <lib/fdf/arena.h>
#include <lib/fdf/cpp/channel_read.h>
#include <lib/fdf/dispatcher.h>
#include <lib/fdf/types.h>
#include <lib/sync/completion.h>
#include <lib/sync/cpp/completion.h>
#include <lib/zx/event.h>

#include <zxtest/zxtest.h>

class RuntimeTestCase : public zxtest::Test {
 public:
  // Registers a wait_async request on |ch| and signals |completion| once it
  // is ready for reading.
  static void SignalOnChannelReadable(fdf_handle_t ch, fdf_dispatcher_t* dispatcher,
                                      sync_completion_t* completion);

  // Registers a wait_async request on |ch| and blocks until it is ready for reading.
  static void WaitUntilReadReady(fdf_handle_t ch, fdf_dispatcher_t* dispatcher);

  // Reads a message from |ch| and asserts that it matches the wanted parameters.
  // If |out_arena| is provided, it will be populated with the transferred arena.
  static void AssertRead(fdf_handle_t ch, void* want_data, size_t want_num_bytes,
                         zx_handle_t* want_handles, uint32_t want_num_handles,
                         fdf_arena_t** out_arena = nullptr);

  // Returns a fake driver pointer that can be used with driver_context APIs.
  // Do not try to access the internals of the pointer.
  const void* CreateFakeDriver() {
    // We don't actually need a real pointer.
    int driver = next_driver_;
    next_driver_++;
    return reinterpret_cast<const void*>(driver);
  }

  // Example usage:
  //   DispatcherShutdownObserver observer;
  //   driver_runtime::Dispatcher* dispatcher;
  //   zx_status_t status =
  //       driver_runtime::Dispatcher::Create(..., observer.fdf_observer(), &dispatcher);
  //   ...
  //   dispatcher->Destroy();
  //   ASSERT_OK(observer.WaitUntilShutdown());
  class DispatcherShutdownObserver {
   public:
    // |require_callback| specifies whether the destructor will check that the callback was called.
    // This can be set to false for tests that expect construction of the dispatcher to fail,
    // but want to pass in a valid observer.
    explicit DispatcherShutdownObserver(bool require_callback = true)
        : require_callback_(require_callback) {
      observer_.fdf_observer.handler = DispatcherDestructedHandler;
    }

    ~DispatcherShutdownObserver() {
      if (require_callback_) {
        ASSERT_TRUE(observer_.signal.signaled());
      }
    }

    DispatcherShutdownObserver(const DispatcherShutdownObserver&) = delete;
    DispatcherShutdownObserver& operator=(const DispatcherShutdownObserver&) = delete;
    DispatcherShutdownObserver& operator=(DispatcherShutdownObserver&&) = delete;
    DispatcherShutdownObserver(DispatcherShutdownObserver&&) = delete;

    zx_status_t WaitUntilShutdown() { return observer_.signal.Wait(zx::time::infinite()); }

    // Returns the observer that can be passed to |driver_runtime::Dispatcher::Create|.
    fdf_dispatcher_shutdown_observer_t* fdf_observer() { return &observer_.fdf_observer; }

    // Returns the dispatcher that was shutdown, nullptr if no shutdown event has occurred.
    fdf_dispatcher_t* shutdown_dispatcher() { return shutdown_dispatcher_; }

   private:
    struct ShutdownObserver {
      fdf_dispatcher_shutdown_observer_t fdf_observer;
      libsync::Completion signal;
    };

    static void DispatcherDestructedHandler(fdf_dispatcher_t* dispatcher,
                                            fdf_dispatcher_shutdown_observer_t* fdf_observer) {
      DispatcherShutdownObserver* observer =
          reinterpret_cast<DispatcherShutdownObserver*>(fdf_observer);
      observer->shutdown_dispatcher_ = dispatcher;
      observer->observer_.signal.Signal();
    }

    ShutdownObserver observer_;
    bool require_callback_;
    fdf_dispatcher_t* shutdown_dispatcher_ = nullptr;
  };

 private:
  int next_driver_ = 1;
};

#endif  // SRC_DEVICES_BIN_DRIVER_RUNTIME_RUNTIME_TEST_CASE_H_
