// Copyright 2019 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_LIB_DEV_OPERATION_INCLUDE_LIB_OPERATION_OPERATION_H_
#define SRC_DEVICES_LIB_DEV_OPERATION_INCLUDE_LIB_OPERATION_OPERATION_H_

#include <zircon/assert.h>
#include <zircon/compiler.h>

#include <optional>
#include <tuple>
#include <utility>

#include <ddk/debug.h>
#include <fbl/algorithm.h>
#include <fbl/auto_lock.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/mutex.h>

namespace operation {

// A problem exists whereby a series of drivers reuse the same object as it
// traverses the driver stack for a specific subsystem. There exists a public
// section specified by a banjo protocol, along with a private section for
// each layer in driver stack appended to the end of it like so:
//
// ---------------------
// | Public Definition |
// ---------------------
// | Driver 1 Private  |
// ---------------------
// | Driver 2 Private  |
// ---------------------
// |        ...        |
// ---------------------
// | Driver N Private  |
// ---------------------
//
// Driver N in this case would perform the allocation of the entire struct.
// Driver 1 in the example above would be the device driver which talks
// directly to hardware. The request would only be "owned" by a single
// driver at a time, but only Driver N (the one who allocated the request)
// would be allowed to free it.
//
// This library provides a generic solution to the private section problem
// which exists for types such as usb_request_t, node_operation_t,
// block_op_t, and others. Specialized wrappers for each of those types
// can be built on top this library.
//
// operation::Operation and operation::BorrowedOperation provide some additional
// safety to prevent leaks and out of bounds accesses. They will ensure that the
// underlying buffer is returned to the caller, or delete it if the current
// owner was responsible for allocating the request. In addition, they help
// provide an easy way to determine the size of the request by simply specifying
// the parent device's operation size.
//
// operation::OperationPool provides a simple pool that allows reuse of
// pre-allocated operation::Operation objects.
//
// operation::{Borrowed,}OperationQueue provide safe queues to place operations
// in while they are pending. These queues rely on intrusive node data built
// into the wrapper type, stored in the private storage section.
//
// operation::{Borrowed,}OperationList provides lists to place operations in
// while they are pending. Operations cannot be stored in both an
// operation::{Borrowed,}OperationQueue and operation::{Borrowed,}Operation:List
// in the same driver layer, as they both use the same memory to store
// the intrusive node data.
//
// In order to use make use of the Operation and OperationNode classes, a new
// type must be created which inherits from it like so:
//
// class Foo : public Operation<Foo, OperationTraits, void>;
// class Bar : public BorrowedOperation<Bar, OperationTraits, CallbackTraits, void>;
//
// OperationTraits must be a type which implements the following function
// and type signatures:
//
//    // Defines public definition which is wrapped.
//    using OperationType = foo_operation_t;
//
//    // Performs an allocation for the operation.
//    static OperationType* Alloc(size_t op_size);
//
//    // Frees the allocation created by Alloc above.
//    static void Free(OperationType* op);
//
// CallbackTraits must be a type which implements the following function
// and type signatures:
//
//    // The type here can be anything. It should match the callback provided to
//    // the BorrowedOperation constructor.
//    using CallbackType = void(void* ctx, ARGS, foo_operation_t*);
//
//    // In case Complete is not called by BorrowedOperation owners, these are
//    // the args to trigger Complete with.
//    static std::tuple<ARGS> AutoCompleteArgs();
//
//    // Should call the callback, transforming and positioning args as necessary.
//    static void Callback(CallbackType*, void*, OperationType*, ARGS);
//
//    Where ARGS is a variadic number of types left to the implementer.
//

template <typename T, typename OperationTraits, typename CallbackTraits, typename Storage = void>
class OperationNode;

template <typename D, typename OperationTraits, typename CallbackTraits, typename Storage>
class OperationBase {
 public:
  using NodeType = OperationNode<D, OperationTraits, CallbackTraits, Storage>;
  using OperationType = typename OperationTraits::OperationType;

  OperationType* take() __WARN_UNUSED_RESULT {
    auto* tmp = operation_;
    operation_ = nullptr;
    return tmp;
  }

  OperationType* operation() const { return operation_; }

  static constexpr size_t OperationSize(size_t parent_op_size) {
    return fbl::round_up(parent_op_size, kAlignment) + sizeof(NodeType);
  }

  size_t size() const { return node_offset_ + sizeof(NodeType); }

  // Returns private node stored inline
  NodeType* node() {
    auto* node =
        reinterpret_cast<NodeType*>(reinterpret_cast<uintptr_t>(operation_) + node_offset_);
    return node;
  }

  Storage* private_storage() {
    static_assert(!std::is_same<Storage, void>::value,
                  "private_storage not available on void type.");
    return node()->private_storage();
  }

 protected:
  OperationBase(OperationType* operation, size_t parent_op_size, bool allow_destruct = true)
      : operation_(operation),
        node_offset_(fbl::round_up(parent_op_size, kAlignment)),
        allow_destruct_(allow_destruct) {
    ZX_DEBUG_ASSERT(operation != nullptr);
  }

  OperationBase(OperationBase&& other)
      : operation_(other.operation_),
        node_offset_(other.node_offset_),
        allow_destruct_(other.allow_destruct_) {
    other.operation_ = nullptr;
  }

  OperationBase& operator=(OperationBase&& other) {
    operation_ = other.operation_;
    node_offset_ = other.node_offset_;
    allow_destruct_ = other.allow_destruct_;
    other.operation_ = nullptr;
    return *this;
  }

  OperationBase(const OperationBase& other) = delete;
  OperationBase& operator=(const OperationBase& other) = delete;

  OperationType* operation_;
  zx_off_t node_offset_;
  bool allow_destruct_;

 private:
  static constexpr size_t kAlignment = alignof(NodeType);
};

template <typename D, typename OperationTraits, typename Storage = void>
class Operation : public OperationBase<D, OperationTraits, void, Storage> {
 public:
  using BaseClass = OperationBase<D, OperationTraits, void, Storage>;
  using NodeType = OperationNode<D, OperationTraits, void, Storage>;
  using OperationType = typename OperationTraits::OperationType;

  // Creates a new operation with payload space of data_size.
  static std::optional<D> Alloc(size_t parent_op_size) {
    const size_t op_size = BaseClass::OperationSize(parent_op_size);
    OperationType* op = OperationTraits::Alloc(op_size);
    if (op == nullptr) {
      return std::nullopt;
    }

    D out(op, parent_op_size);
    new (out.node()) NodeType(out.node_offset_);
    return std::move(out);
  }

  // Must be called with |operation| allocated via OperationTraits::Alloc.
  Operation(OperationType* operation, size_t parent_op_size, bool allow_destruct = true)
      : BaseClass(operation, parent_op_size, allow_destruct) {}

  Operation(Operation&& other)
      : BaseClass(other.operation_, other.node_offset_, other.allow_destruct_) {
    other.operation_ = nullptr;
  }

  Operation& operator=(Operation&& other) {
    BaseClass::operator=(std::move(other));
    return *this;
  }

  ~Operation() {
    if (!BaseClass::allow_destruct_) {
      return;
    }
    Release();
  }

  void Release() {
    ZX_DEBUG_ASSERT(BaseClass::allow_destruct_);
    if (BaseClass::operation_) {
      BaseClass::node()->NodeType::~NodeType();
      OperationTraits::Free(BaseClass::take());
    }
  }
};

// Similar to operation::Operation, but it doesn't call free on destruction.
// This should be used to wrap NodeType* objects allocated in other
// drivers.
// NOTE: This WILL auto-complete the request on destruction if allow_destruct is set.
template <typename D, typename OperationTraits, typename CallbackTraits, typename Storage = void>
class BorrowedOperation : public OperationBase<D, OperationTraits, CallbackTraits, Storage> {
 public:
  using BaseClass = OperationBase<D, OperationTraits, CallbackTraits, Storage>;
  using NodeType = OperationNode<D, OperationTraits, CallbackTraits, Storage>;
  using OperationType = typename OperationTraits::OperationType;
  using CallbackType = typename CallbackTraits::CallbackType;

  BorrowedOperation(OperationType* operation, const CallbackType* complete_cb, void* cookie,
                    size_t parent_op_size, bool allow_destruct = true)
      : BaseClass(operation, parent_op_size, allow_destruct) {
    new (BaseClass::node()) NodeType(BaseClass::node_offset_, complete_cb, cookie);
  }

  BorrowedOperation(OperationType* operation, size_t parent_op_size, bool allow_destruct = true)
      : BaseClass(operation, parent_op_size, allow_destruct) {
    ZX_DEBUG_ASSERT(BaseClass::node()->node_offset() != 0);
  }

  BorrowedOperation(BorrowedOperation&& other)
      : BaseClass(other.operation_, other.node_offset_, other.allow_destruct_) {
    other.operation_ = nullptr;
  }

  BorrowedOperation& operator=(BorrowedOperation&& other) {
    BaseClass::operator=(std::move(other));
    return *this;
  }

  ~BorrowedOperation() {
    ZX_ASSERT(!BaseClass::allow_destruct_ || BaseClass::operation_ == nullptr);
  }

  // Must be called by the processor when the operation has completed or failed.
  // The operation and any virtual or physical memory obtained from it is no
  // longer valid after Complete is called.
  template <typename... Args>
  void Complete(Args... args) {
    ZX_DEBUG_ASSERT(BaseClass::allow_destruct_);
    if (BaseClass::operation_) {
      auto* complete_cb = BaseClass::node()->complete_cb();
      auto* cookie = BaseClass::node()->cookie();
      BaseClass::node()->NodeType::~NodeType();
      CallbackTraits::Callback(complete_cb, cookie, BaseClass::take(), std::forward<Args>(args)...);
    }
  }
};

// Node storage for operation::Operation and operation::BorrowedOperation. Does not maintain
// ownership of underlying NodeType*. Must be transformed back into
// appopriate wrapper type to maintain correct ownership.
// It is strongly recommended to use operation::OperationPool and operation::OperationQueue to
// avoid ownership pitfalls.
template <typename T, typename OperationTraits, typename CallbackTraits, typename Storage>
class OperationNode : public fbl::DoublyLinkedListable<
                          OperationNode<T, OperationTraits, CallbackTraits, Storage>*> {
 public:
  using OperationType = typename OperationTraits::OperationType;
  using CallbackType = typename CallbackTraits::CallbackType;

  OperationNode(zx_off_t node_offset, const CallbackType* complete_cb, void* cookie)
      : node_offset_(node_offset), complete_cb_(complete_cb), cookie_(cookie) {}

  ~OperationNode() = default;

  T operation(bool allow_destruct = true) const {
    return T(reinterpret_cast<OperationType*>(reinterpret_cast<uintptr_t>(this) - node_offset_),
             node_offset_, allow_destruct);
  }

  zx_off_t node_offset() const { return node_offset_; }

  const CallbackType* complete_cb() const { return complete_cb_; }

  void* cookie() const { return cookie_; }

  Storage* private_storage() { return &private_storage_; }

 private:
  const zx_off_t node_offset_;
  const CallbackType* complete_cb_;
  void* cookie_;
  Storage private_storage_;
};

// Specialized version for when complete_cb is not required.
template <typename T, typename OperationTraits, typename Storage>
class OperationNode<T, OperationTraits, void, Storage>
    : public fbl::DoublyLinkedListable<OperationNode<T, OperationTraits, void, Storage>*> {
 public:
  using OperationType = typename OperationTraits::OperationType;

  explicit OperationNode(zx_off_t node_offset) : node_offset_(node_offset) {}

  ~OperationNode() = default;

  T operation(bool allow_destruct = true) const {
    return T(reinterpret_cast<OperationType*>(reinterpret_cast<uintptr_t>(this) - node_offset_),
             node_offset_, allow_destruct);
  }

  zx_off_t node_offset() const { return node_offset_; }

  Storage* private_storage() { return &private_storage_; }

 private:
  const zx_off_t node_offset_;
  Storage private_storage_;
};

// Specialized version for when no additional storage is required.
template <typename T, typename OperationTraits, typename CallbackTraits>
class OperationNode<T, OperationTraits, CallbackTraits, void>
    : public fbl::DoublyLinkedListable<OperationNode<T, OperationTraits, CallbackTraits, void>*> {
 public:
  using OperationType = typename OperationTraits::OperationType;
  using CallbackType = typename CallbackTraits::CallbackType;

  OperationNode(zx_off_t node_offset, const CallbackType* complete_cb, void* cookie)
      : node_offset_(node_offset), complete_cb_(complete_cb), cookie_(cookie) {}

  ~OperationNode() = default;

  T operation(bool allow_destruct = true) const {
    return T(reinterpret_cast<OperationType*>(reinterpret_cast<uintptr_t>(this) - node_offset_),
             node_offset_, allow_destruct);
  }

  zx_off_t node_offset() const { return node_offset_; }

  const CallbackType* complete_cb() const { return complete_cb_; }

  void* cookie() const { return cookie_; }

 private:
  const zx_off_t node_offset_;
  const CallbackType* complete_cb_;
  void* cookie_;
};

// Specialized version for when no additional storage is required, and
// complete_cb is not required.
template <typename T, typename OperationTraits>
class OperationNode<T, OperationTraits, void, void>
    : public fbl::DoublyLinkedListable<OperationNode<T, OperationTraits, void, void>*> {
 public:
  using OperationType = typename OperationTraits::OperationType;

  OperationNode(zx_off_t node_offset) : node_offset_(node_offset) {}

  ~OperationNode() = default;

  T operation(bool allow_destruct = true) const {
    return T(reinterpret_cast<OperationType*>(reinterpret_cast<uintptr_t>(this) - node_offset_),
             node_offset_, allow_destruct);
  }

  zx_off_t node_offset() const { return node_offset_; }

 private:
  const zx_off_t node_offset_;
};

// Convenience queue wrapper around fbl::DoublyLinkedList<T>.
// The class is thread-safe.
template <typename OpType, typename OperationTraits, typename CallbackTraits, typename Storage>
class BaseQueue {
 public:
  using NodeType = OperationNode<OpType, OperationTraits, CallbackTraits, Storage>;

  DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_node, node, NodeType* (C::*)());
  static_assert(has_node<OpType>::value,
                "OpType must implement OperationNode<OpType, OperationTraits, CallbackTraits, "
                "Storage>* node()");

  BaseQueue() {}

  ~BaseQueue() { Release(); }

  BaseQueue(BaseQueue&& other) {
    fbl::AutoLock al(&other.lock_);
    queue_.swap(other.queue_);
  }

  BaseQueue& operator=(BaseQueue&& other) {
    fbl::AutoLock al1(&lock_);
    fbl::AutoLock al2(&other.lock_);
    queue_.clear();
    queue_.swap(other.queue_);
    return *this;
  }

  void push(OpType op) {
    fbl::AutoLock al(&lock_);
    auto* node = op.node();
    queue_.push_front(node);
    // Must prevent Complete/Release from being called in destructor.
    __UNUSED auto dummy = op.take();
  }

  void push_next(OpType op) {
    fbl::AutoLock al(&lock_);
    auto* node = op.node();
    queue_.push_back(node);
    // Must prevent Complete/Release from being called in destructor.
    __UNUSED auto dummy = op.take();
  }

  std::optional<OpType> pop() {
    fbl::AutoLock al(&lock_);
    auto* node = queue_.pop_back();
    if (node) {
      return std::move(node->operation());
    }
    return std::nullopt;
  }

  std::optional<OpType> pop_last() {
    fbl::AutoLock al(&lock_);
    auto* node = queue_.pop_front();
    if (node) {
      return std::move(node->operation());
    }
    return std::nullopt;
  }

  bool erase(OpType* op) {
    fbl::AutoLock al(&lock_);
    auto* node = op->node();
    bool erased = queue_.erase(*node) != nullptr;
    return erased;
  }

  bool is_empty() {
    fbl::AutoLock al(&lock_);
    return queue_.is_empty();
  }

  // Releases all ops stored in the queue.
  void Release() {
    fbl::AutoLock al(&lock_);
    while (!queue_.is_empty()) {
      // Transform back into operation to force correct destructor to run.
      __UNUSED auto op = queue_.pop_back()->operation();
    }
  }

 protected:
  fbl::Mutex lock_;
  fbl::DoublyLinkedList<NodeType*> queue_ __TA_GUARDED(lock_);
};

template <typename D, typename OperationTraits, typename Storage = void>
using OperationQueue = BaseQueue<D, OperationTraits, void, Storage>;

template <typename D, typename OperationTraits, typename CallbackTraits, typename Storage = void>
class BorrowedOperationQueue : public BaseQueue<D, OperationTraits, CallbackTraits, Storage> {
 public:
  using BaseClass = BaseQueue<D, OperationTraits, CallbackTraits, Storage>;

  // Use constructor.
  using BaseClass::BaseClass;

  template <typename... Args>
  void CompleteAll(Args... args) {
    for (auto op = BaseClass::pop(); op; op = BaseClass::pop()) {
      op->Complete(std::forward<Args>(args)...);
    }
  }
};

// A driver may use operation::OperationPool for recycling their own operations.
template <typename OpType, typename OperationTraits, typename Storage = void>
class OperationPool : protected BaseQueue<OpType, OperationTraits, void, Storage> {
 public:
  using BaseClass = BaseQueue<OpType, OperationTraits, void, Storage>;

  // Use constructor.
  using BaseClass::BaseClass;

  // Operate like a stack rather than a queue.
  void push(OpType op) { BaseClass::push_next(std::forward<OpType>(op)); }
  using BaseClass::pop;

  using BaseClass::Release;
};

// Convenience list wrapper around fbl::DoublyLinkedList<T>.
// The class is not thread-safe.
template <typename OpType, typename OperationTraits, typename CallbackTraits, typename Storage>
class BaseList {
 public:
  using NodeType = OperationNode<OpType, OperationTraits, CallbackTraits, Storage>;

  DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_node, node, NodeType* (C::*)());
  static_assert(has_node<OpType>::value,
                "OpType must implement OperationNode<OpType, OperationTraits, CallbackTraits, "
                "Storage>* node()");

  BaseList() {}

  ~BaseList() { Release(); }

  BaseList(BaseList&& other) {
    list_.swap(other.list_);
    size_t temp = size_;
    size_ = other.size_;
    other.size_ = temp;
  }

  BaseList& operator=(BaseList&& other) {
    list_.clear();
    list_.swap(other.list_);
    size_ = other.size_;
    other.size_ = 0;
    return *this;
  }

  // Adds the operation to the end of the list.
  void push_back(OpType* op) {
    auto* node = op->node();
    list_.push_back(node);
    ++size_;
  }

  // Returns the index of the given operation in the list, or std::nullopt if none was found.
  std::optional<size_t> find(OpType* op) {
    size_t i = 0;
    for (auto iter = list_.begin(); iter != list_.end(); ++iter) {
      auto test_op = iter->operation(/* allow_destruct */ false);
      if (test_op.operation() == op->operation()) {
        return i;
      }
      ++i;
    }
    return std::nullopt;
  }

  // Returns the operation at the start of the list.
  std::optional<OpType> begin() {
    if (size_ == 0) {
      return std::nullopt;
    }
    auto iter = list_.begin();
    return iter->operation(/* allow_destruct */ false);
  }

  // Returns the operation in the list before |op|, or std::nullopt if |op| is the
  // start of the list.
  std::optional<OpType> prev(OpType* op) {
    auto* node = op->node();
    auto iter = list_.make_iterator(*node);
    if (iter == list_.begin()) {
      return std::nullopt;
    }
    --iter;
    return std::move(iter->operation(/* allow_destruct */ false));
  }

  // Returns the operation in the list following |op|, or std::nullopt if |op| is the
  // end of the list.
  std::optional<OpType> next(OpType* op) {
    auto* node = op->node();
    auto iter = list_.make_iterator(*node);
    ++iter;
    if (iter == list_.end()) {
      return std::nullopt;
    }
    return std::move(iter->operation(/* allow_destruct */ false));
  }

  // Deletes the first instance of the operation found in the list.
  // Returns whether an operation was deleted.
  bool erase(OpType* op) {
    auto* node = op->node();
    bool erased = list_.erase(*node) != nullptr;
    if (erased) {
      --size_;
    }
    return erased;
  }

  // Returns the number of ops in the list.
  size_t size() const { return size_; }

  // Releases all ops stored in the list.
  void Release() {
    list_.clear();
    size_ = 0;
  }

 protected:
  fbl::DoublyLinkedList<NodeType*> list_;
  size_t size_ = 0;
};

template <typename D, typename OperationTraits, typename CallbackTraits, typename Storage = void>
using BorrowedOperationList = BaseList<D, OperationTraits, CallbackTraits, Storage>;

template <typename D, typename OperationTraits, typename Storage = void>
using OperationList = BaseList<D, OperationTraits, void, Storage>;

}  // namespace operation

#endif  // SRC_DEVICES_LIB_DEV_OPERATION_INCLUDE_LIB_OPERATION_OPERATION_H_
