// Copyright 2016 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 <lib/fdio/limits.h>
#include <stdint.h>

#include <type_traits>

#include <fbl/function.h>
#include <zircon/compiler.h>
#include <zircon/fidl.h>
#include <zircon/types.h>

// Fuchsia-io limits.
//
// TODO(FIDL-127): Compute these values with the "union of all fuchsia-io"
// messages.
#define ZXFIDL_MAX_MSG_BYTES    (FDIO_CHUNK_SIZE * 2)
#define ZXFIDL_MAX_MSG_HANDLES  (16)

// indicates the callback is taking responsibility for the
// channel receiving incoming messages.
//
// Unlike ERR_DISPATCHER_INDIRECT, this callback is propagated
// through ReadMessage.
#define ERR_DISPATCHER_ASYNC ZX_ERR_ASYNC

// indicates that this was a close message and that no further
// callbacks should be made to the dispatcher
#define ERR_DISPATCHER_DONE ZX_ERR_STOP

namespace fs {

// FidlConnection contains enough context to respond to a FIDL message.
//
// It contains both the underlying fidl transaction, as well as the channel and txid,
// which are necessary for responding to fidl messages.
class FidlConnection {
public:
    // TODO(smklein): convert channel to a zx::unowned_channel.
    FidlConnection(fidl_txn_t txn, zx_handle_t channel, zx_txid_t txid)
        : txn_(std::move(txn)), channel_(std::move(channel)), txid_(std::move(txid)) {}

    fidl_txn_t* Txn() {
        return &txn_;
    }

    zx_txid_t Txid() const {
        return txid_;
    }

    zx_handle_t Channel() const {
        return channel_;
    }

    // Utilizes a |fidl_txn_t| object as a wrapped FidlConnection.
    //
    // Only safe to call if |txn| was previously returned by |FidlConnection.Txn()|.
    static const FidlConnection* FromTxn(const fidl_txn_t* txn);

    // Copies txn into a new FidlConnection.
    //
    // This may be useful for copying a FidlConnection out of stack-allocated scope,
    // so a response may be generated asynchronously.
    //
    // Only safe to call if |txn| was previously returned by |FidlConnection.Txn()|.
    static FidlConnection CopyTxn(const fidl_txn_t* txn);

private:
    fidl_txn_t txn_;
    zx_handle_t channel_;
    zx_txid_t txid_;
};

inline const FidlConnection* FidlConnection::FromTxn(const fidl_txn_t* txn) {
    static_assert(std::is_standard_layout<FidlConnection>::value,
                  "Cannot cast from non-standard layout class");
    static_assert(offsetof(FidlConnection, txn_) == 0,
                  "FidlConnection must be convertable to txn");
    return reinterpret_cast<const FidlConnection*>(txn);
}

inline FidlConnection FidlConnection::CopyTxn(const fidl_txn_t* txn) {
    static_assert(std::is_trivially_copyable<FidlConnection>::value, "Cannot trivially copy");
    return *FromTxn(txn);
}

// callback to process a FIDL message.
// - |msg| is a decoded FIDL message.
// - return value of ERR_DISPATCHER_{INDIRECT,ASYNC} indicates that the reply is
//   being handled by the callback (forwarded to another server, sent later,
//   etc, and no reply message should be sent).
// - WARNING: Once this callback returns, usage of |msg| is no longer
//   valid. If a client transmits ERR_DISPATCHER_{INDIRECT,ASYNC}, and intends
//   to respond asynchronously, they must copy the fields of |msg| they
//   wish to use at a later point in time.
// - otherwise, the return value is treated as the status to send
//   in the rpc response, and msg.len indicates how much valid data
//   to send.  On error return msg.len will be set to 0.
using FidlDispatchFunction = fbl::Function<zx_status_t(fidl_msg_t* msg, FidlConnection* txn)>;

// Attempts to read and dispatch a FIDL message.
//
// If a message cannot be read, returns an error instead of blocking.
zx_status_t ReadMessage(zx_handle_t h, FidlDispatchFunction dispatch);

// Synthesizes a FIDL close message.
//
// This may be invoked when a channel is closed, to simulate dispatching
// to the same close function.
zx_status_t CloseMessage(FidlDispatchFunction dispatch);

} // namespace fs
