// Copyright 2018 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_ASYNC_CPP_TRAP_H_
#define LIB_ASYNC_CPP_TRAP_H_

#include <lib/async/trap.h>
#include <lib/fit/function.h>
#include <lib/zx/guest.h>

#include <utility>

namespace async {

// Holds context for a bell trap and its handler.
//
// After successfully posting setting the trap, the client is responsible for retaining
// the structure in memory (and unmodified) until the guest has been destroyed or the
// dispatcher shuts down.  There is no way to cancel a trap which has been set.
//
// Concrete implementations: |async::GuestBellTrap|, |async::GuestBellTrapMethod|.
// Please do not create subclasses of GuestBellTrapBase outside of this library.
class GuestBellTrapBase {
protected:
    explicit GuestBellTrapBase(async_guest_bell_trap_handler_t* handler);
    ~GuestBellTrapBase();

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

public:
    // Sets a bell trap in the guest to be handled asynchronously via a handler.
    //
    // |guest| is the handle of the guest the trap will be set on.
    // |addr| is the base address for the trap in the guest's physical address space.
    // |length| is the size of the trap in the guest's physical address space.
    //
    // Returns |ZX_OK| if the trap was successfully set.
    // Returns |ZX_ERR_ACCESS_DENIED| if the guest does not have |ZX_RIGHT_WRITE|.
    // Returns |ZX_ERR_ALREADY_EXISTS| if a bell trap with the same |addr| exists.
    // Returns |ZX_ERR_INVALID_ARGS| if |addr| or |length| are invalid.
    // Returns |ZX_ERR_OUT_OF_RANGE| if |addr| or |length| are out of range of the
    // address space.
    // Returns |ZX_ERR_WRONG_TYPE| if |guest| is not a handle to a guest.
    // Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
    // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
    //
    // This operation is thread-safe.
    zx_status_t SetTrap(async_dispatcher_t* dispatcher, const zx::guest& guest,
                        zx_vaddr_t addr, size_t length);

protected:
    template <typename T>
    static T* Dispatch(async_guest_bell_trap_t* trap) {
        static_assert(offsetof(GuestBellTrapBase, trap_) == 0, "");
        auto self = reinterpret_cast<GuestBellTrapBase*>(trap);
        return static_cast<T*>(self);
    }

private:
    async_guest_bell_trap_t trap_;
};

// A bell trap whose handler is bound to a |async::Task::Handler| function.
//
// Prefer using |async::GuestBellTrapMethod| instead for binding to a fixed class member
// function since it is more efficient to dispatch.
class GuestBellTrap final : public GuestBellTrapBase {
public:
    // Handles an asynchronous trap access.
    //
    // The |status| is |ZX_OK| if the bell was received and |bell| contains the
    // information from the packet, otherwise |bell| is null.
    using Handler = fit::function<void(async_dispatcher_t* dispatcher, async::GuestBellTrap* trap,
                                       zx_status_t status, const zx_packet_guest_bell_t* bell)>;

    explicit GuestBellTrap(Handler handler = nullptr);
    ~GuestBellTrap();

    void set_handler(Handler handler) { handler_ = std::move(handler); }
    bool has_handler() const { return !!handler_; }

private:
    static void CallHandler(async_dispatcher_t* dispatcher, async_guest_bell_trap_t* trap,
                            zx_status_t status, const zx_packet_guest_bell_t* bell);

    Handler handler_;
};

// A bell trap whose handler is bound to a fixed class member function.
//
// Usage:
//
// class Foo {
//     void Handle(async_dispatcher_t* dispatcher, async::GuestBellTrapBase* trap, zx_status_t status,
//                 const zx_packet_guest_bell_t* bell) { ... }
//     async::GuestBellTrapMethod<Foo, &Foo::Handle> trap_{this};
// };
template <class Class,
          void (Class::*method)(async_dispatcher_t* dispatcher, async::GuestBellTrapBase* trap,
                                zx_status_t status, const zx_packet_guest_bell_t* bell)>
class GuestBellTrapMethod final : public GuestBellTrapBase {
public:
    explicit GuestBellTrapMethod(Class* instance)
        : GuestBellTrapBase(&GuestBellTrapMethod::CallHandler),
          instance_(instance) {}

private:
    static void CallHandler(async_dispatcher_t* dispatcher, async_guest_bell_trap_t* trap,
                            zx_status_t status, const zx_packet_guest_bell_t* bell) {
        auto self = Dispatch<GuestBellTrapMethod>(trap);
        (self->instance_->*method)(dispatcher, self, status, bell);
    }

    Class* const instance_;
};

} // namespace async

#endif  // LIB_ASYNC_CPP_TRAP_H_
