// 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_HANDLE_H_
#define SRC_DEVICES_BIN_DRIVER_RUNTIME_HANDLE_H_

#include <lib/fdf/types.h>
#include <lib/fit/nullable.h>
#include <stdint.h>

#include <array>

#include <fbl/auto_lock.h>
#include <fbl/intrusive_single_list.h>
#include <fbl/ref_ptr.h>

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

namespace driver_runtime {

class Handle;

// Callable object for destroying uniquely owned handles.
struct HandleDestroyer {
  inline void operator()(Handle* handle);
};

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

// A handle is how a process refers to runtime objects such as fdf_channels.
class Handle : public fbl::SinglyLinkedListable<Handle*> {
 public:
  // Returns a unique reference to a newly created handle.
  // Takes ownership of |object|.
  static HandleOwner Create(fbl::RefPtr<Object> object);

  // This needs to be public for |HandleTableArena|.
  explicit Handle(fbl::RefPtr<Object> object = nullptr, fdf_handle_t value = FDF_HANDLE_INVALID)
      : object_(std::move(object)), value_(value) {}

  // Clears handle state specific to this lifetime.
  // The handle |value| is preserved, as it is used to generate a new handle value
  // referring to the same handle object.
  void Reset() { object_ = nullptr; }

  // Returns whether the handle exists in the handle table.
  static bool HandleExists(fdf_handle_t value) { return MapValueToHandle(value); }

  // Maps |value| to the runtime's Handle object.
  // The Handle must have previously been created with |Create|.
  // This does not provide ownership to the Handle. To destroy the Handle,
  // the caller should use |TakeOwnership|.
  static Handle* MapValueToHandle(fdf_handle_t value);

  // Returns whether |handle_value| is of type fdf_handle_t.
  // Does not do any validation on whether it is a valid fdf handle.
  static bool IsFdfHandle(zx_handle_t handle_value);

  // Returns the object corresponding to |value_|.
  template <typename T>
  zx_status_t GetObject(fbl::RefPtr<T>* out_object) {
    // TODO(https://fxbug.dev/42167564): we should add some type checking once we support more object types.
    *out_object = fbl::RefPtr<T>::Downcast(object());
    if (!*out_object) {
      return ZX_ERR_WRONG_TYPE;
    }
    return ZX_OK;
  }

  // Returns the object corresponding to |handle_value|.
  template <typename T>
  static zx_status_t GetObject(fdf_handle_t handle_value, fbl::RefPtr<T>* out_object) {
    Handle* handle = Handle::MapValueToHandle(handle_value);
    if (!handle) {
      return ZX_ERR_BAD_HANDLE;
    }
    return handle->GetObject<T>(out_object);
  }

  HandleOwner TakeOwnership() { return HandleOwner(this); }

  // Returns the object this handle refers to.
  fbl::RefPtr<Object> object() { return object_; }
  bool has_object() const { return object_ != nullptr; }

  // Returns the handle value which refers to this object.
  fdf_handle_t handle_value() const { return value_; }

 private:
  fbl::RefPtr<Object> object_;
  fdf_handle_t value_;
};

// HandleTableArena provides the memory backing the Handle objects.
// This class is thread-safe.
class HandleTableArena {
 public:
  // TODO(https://fxbug.dev/42167621): fine-tune this numbers, they were randomly selected.
  static constexpr size_t kMaxNumHandles = 64ull * 1024;
  // The number of tables stored in |handle_table_dir_|.
  static constexpr size_t kNumTables = 64;
  // The number of handles per table.
  static constexpr size_t kHandlesPerTable = kMaxNumHandles / kNumTables;

  HandleTableArena() : handle_table_dir_{&initial_handles_} {}

  ~HandleTableArena() {
    // fbl::SinglyLinkedList does not like deleting non-empty lists containing
    // unmanaged pointers. We don't need to free the handle pointers,
    // as the tables backing them will be deleted.
    free_handles_.clear();
    for (const auto& table : handle_table_dir_) {
      // Make sure we don't accidentally delete the |handles_| array that was
      // allocated as part of the class.
      if (table && table != &initial_handles_) {
        delete table;
      }
    }
  }

  // Alloc returns storage for a handle.
  // |out_handle_value| is the generated handle value referring to the returned Handle object.
  Handle* Alloc(fdf_handle_t* out_handle_value);

  // Clears handle state specific to this lifetime and adds the handle to the free
  // list for re-use.
  void Delete(Handle* handle) {
    handle->Reset();

    fbl::AutoLock lock(&lock_);
    free_handles_.push_front(handle);
    num_allocated_--;
  }

  // Returns the handle located in the handle table pointed to by |table|, at |index|.
  // Returns nullptr if the indexes are invalid, or do not point to an allocated handle.
  fit::nullable<Handle*> GetExistingHandle(uint32_t table, uint32_t index);

  // Returns the number of handles currently allocated (does not include freed handles).
  uint32_t num_allocated() {
    fbl::AutoLock lock(&lock_);
    return num_allocated_;
  }

 private:
  // Returns a pointer to memory that can be used to construct a Handle object.
  // |out_table| and |out_index| describes the location of that memory.
  Handle* AllocHandleMemoryLocked(uint32_t* out_table, uint32_t* out_index) __TA_REQUIRES(&lock_);

  fbl::Mutex lock_;
  // The first handle table allocated as part of the class.
  std::array<Handle, kHandlesPerTable> initial_handles_ __TA_GUARDED(&lock_);
  // Directory which holds all the handle tables, including |initial_handles_|.
  // More handle tables are allocated and added to this as needed.
  std::array<std::array<Handle, kHandlesPerTable>*, kNumTables> handle_table_dir_
      __TA_GUARDED(&lock_);

  // Indexes pointing to the next available memory that can be used for handle allocation.
  // Index into |handle_table_dir_|.
  uint32_t dir_index_ __TA_GUARDED(&lock_) = 0;
  // Index into the handle table referred to by|dir_index_|.
  uint32_t handles_index_ __TA_GUARDED(&lock_) = 0;

  // Handles that have been freed are recycled into |free_handles_|.
  fbl::SinglyLinkedList<Handle*> free_handles_ __TA_GUARDED(&lock_);

  // Number of handles currently allocated (does not include freed handles).
  uint32_t num_allocated_ __TA_GUARDED(&lock_) = 0;
};

extern HandleTableArena gHandleTableArena;

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

}  // namespace driver_runtime

#endif  //  SRC_DEVICES_BIN_DRIVER_RUNTIME_HANDLE_H_
