// Copyright 2017 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.

#pragma once

#include <async/wait.h>

#ifdef __cplusplus

#include <fbl/function.h>
#include <fbl/macros.h>

namespace async {

// C++ wrapper for a pending wait operation which is automatically canceled
// when it goes out of scope.
//
// This class is NOT thread-safe; it can only be used with single-threaded
// asynchronous dispatchers.
class AutoWait final : private async_wait_t {
public:
    // Handles completion of asynchronous wait operations.
    //
    // Reports the |status| of the wait.  If the status is |ZX_OK| then |signal|
    // describes the signal which was received, otherwise |signal| is null.
    //
    // The result indicates whether the wait should be repeated; it may
    // modify the wait's properties (such as the trigger) before returning.
    //
    // The result must be |ASYNC_WAIT_FINISHED| if |status| was not |ZX_OK|.
    //
    // It is safe for the handler to destroy itself when returning |ASYNC_WAIT_FINISHED|.
    using Handler = fbl::Function<async_wait_result_t(async_t* async,
                                                      zx_status_t status,
                                                      const zx_packet_signal_t* signal)>;

    // Initializes the properties of the wait operation and binds it to an
    // asynchronous dispatcher.
    explicit AutoWait(async_t* async,
                      zx_handle_t object = ZX_HANDLE_INVALID,
                      zx_signals_t trigger = ZX_SIGNAL_NONE,
                      uint32_t flags = 0u);

    // Destroys the wait operation.
    //
    // The wait is canceled automatically if it is still pending.
    ~AutoWait();

    // Gets the asynchronous dispatcher to which this wait has been bound.
    async_t* async() const { return async_; }

    // Returns true if |Begin()| was called successfully but the wait has not
    // completed or been canceled.
    bool is_pending() const { return pending_; }

    // Gets or sets the handler to invoke when the wait completes.
    // Must be set before beginning the wait.
    const Handler& handler() const { return handler_; }
    void set_handler(Handler handler) { handler_ = fbl::move(handler); }

    // The object to wait for signals on.
    zx_handle_t object() const { return async_wait_t::object; }
    void set_object(zx_handle_t object) { async_wait_t::object = object; }

    // The set of signals to wait for.
    zx_signals_t trigger() const { return async_wait_t::trigger; }
    void set_trigger(zx_signals_t trigger) { async_wait_t::trigger = trigger; }

    // Valid flags: |ASYNC_FLAG_HANDLE_SHUTDOWN|.
    uint32_t flags() const { return async_wait_t::flags; }
    void set_flags(uint32_t flags) { async_wait_t::flags = flags; }

    // Begins asynchronously waiting for the object to receive one or more of
    // the trigger signals.
    //
    // This method must not be called when the wait is already pending.
    //
    // See |async_begin_wait()| for details.
    zx_status_t Begin();

    // Cancels the wait.
    //
    // This method does nothing if the wait is not pending.
    //
    // See |async_cancel_wait()| for details.
    void Cancel();

private:
    static async_wait_result_t CallHandler(async_t* async, async_wait_t* wait,
                                           zx_status_t status,
                                           const zx_packet_signal_t* signal);

    async_t* const async_;
    Handler handler_;
    bool pending_ = false;

    DISALLOW_COPY_ASSIGN_AND_MOVE(AutoWait);
};

} // namespace async

#endif // __cplusplus
