// 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_MESSAGE_PACKET_H_
#define SRC_DEVICES_BIN_DRIVER_RUNTIME_MESSAGE_PACKET_H_

#include <lib/fdf/arena.h>
#include <lib/fdf/types.h>

#include <fbl/intrusive_double_list.h>

#include "src/devices/bin/driver_runtime/arena.h"

namespace driver_runtime {

class MessagePacket;

// Callable object for destroying uniquely owned message packets.
struct MessagePacketDestroyer {
  inline void operator()(MessagePacket* message_packet);
};

// MessagePacketOwner wraps a MessagePacket in a unique_ptr that has single
// ownership of the MessagePacket and deletes it whenever it falls out of scope.
using MessagePacketOwner = std::unique_ptr<MessagePacket, MessagePacketDestroyer>;

// Holds the contents of a message written to a channel.
// TODO(https://fxbug.dev/42167912): we should consider recycling deleted packets.
class MessagePacket : public fbl::DoublyLinkedListable<MessagePacketOwner> {
 public:
  static MessagePacketOwner Create(fbl::RefPtr<fdf_arena_t> arena, void* data, uint32_t num_bytes,
                                   zx_handle_t* handles, uint32_t num_handles);

  // Copies the message contents to the parameters provided.
  // Returns ownership of an arena, the data and handles.
  void CopyOut(fdf_arena_t** out_arena, void** out_data, uint32_t* out_num_bytes,
               zx_handle_t** out_handles, uint32_t* out_num_handles);

  // fdf_channel_call treats the leading bytes of the payload as a transaction id of type
  // fdf_txid_t.
  zx_txid_t get_txid() const {
    if (num_bytes_ < sizeof(fdf_txid_t)) {
      return 0;
    }
    return *static_cast<fdf_txid_t*>(data_);
  }

  void set_txid(fdf_txid_t txid) {
    ZX_ASSERT(num_bytes_ >= sizeof(txid));
    *(static_cast<fdf_txid_t*>(data_)) = txid;
  }

  // Returns a reference to the arena.
  // The message packet retains a reference to correctly destruct itself.
  fbl::RefPtr<fdf_arena_t> arena() { return arena_; }
  uint32_t num_bytes() const { return num_bytes_; }
  uint32_t num_handles() const { return num_handles_; }

 private:
  // |MessagePacket| acquires a new reference to the arena written to the channel.
  // The arena is used to create the message packet, as well as being provided
  // to the user on |fdf_channel_write|. The user's reference to the arena will be
  // dropped when the user calls |fdf_arena_t_destroy|.
  MessagePacket(fbl::RefPtr<fdf_arena_t> arena, void* data, uint32_t num_bytes,
                zx_handle_t* handles, uint32_t num_handles)
      : arena_(std::move(arena)),
        data_(data),
        num_bytes_(num_bytes),
        handles_(handles),
        num_handles_(num_handles) {}

  // A private destructor helps to make sure that only our custom deleter is
  // ever used to destroy this object which, in turn, makes it very difficult
  // to not properly recycle the object.
  ~MessagePacket();

  void TakeData(void** out_data) {
    *out_data = data_;
    data_ = nullptr;
  }

  void TakeHandles(zx_handle_t** out_handles) {
    *out_handles = handles_;
    handles_ = nullptr;
  }

  friend struct MessagePacketDestroyer;
  static void Delete(MessagePacket* packet);

  fbl::RefPtr<fdf_arena_t> arena_;
  void* data_;
  uint32_t num_bytes_;
  zx_handle_t* handles_;
  uint32_t num_handles_;
};

// This can't be defined directly in the MessagePacketDestroyer struct definition
// because MessagePacket is an incomplete type at that point.
inline void MessagePacketDestroyer::operator()(MessagePacket* message_packet) {
  MessagePacket::Delete(message_packet);
}

}  // namespace driver_runtime

#endif  //  SRC_DEVICES_BIN_DRIVER_RUNTIME_MESSAGE_PACKET_H_
