// 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

#include <lib/fake-object/object.h>
#include <lib/zx/status.h>
#include <zircon/types.h>

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

namespace fake_object {

zx::status<fbl::RefPtr<Object>> HandleTable::GetLocked(zx_handle_t handle) {
  zx::status status = HandleToIndex(handle);
  if (!status.is_ok() || status.value() >= handles_.size() || !handles_[status.value()]) {
    ftracef("handle = 0x%x, not found\n", handle);
    return zx::error(ZX_ERR_NOT_FOUND);
  }
  auto& obj = handles_[status.value()];
  ftracef("handle = 0x%x, obj = %p, type = %u, index = %zu\n", handle, obj.get(), obj->type(),
          status.value());
  return zx::success(obj);
}

__EXPORT
zx::status<zx_handle_t> HandleTable::Add(fbl::RefPtr<Object> obj) {
  fbl::AutoLock guard(&lock_);
  __UNUSED auto* obj_ptr = obj.get();
  zx_handle_t handle = ZX_HANDLE_INVALID;
  bool found_slot = false;
  size_t idx = 0;

  for (size_t i = 0; i < handles_.size(); ++i) {
    if (!handles_[i]) {
      idx = i;
      handles_[idx] = std::move(obj);
      found_slot = true;
      break;
    }
  }

  if (!found_slot) {
    idx = handles_.size();
    handles_.push_back(std::move(obj));
  }
  handle = IndexToHandle(idx);
  ftracef("handle = 0x%x, obj = %p, type = %u, index = %zu\n", handle, obj_ptr, obj_ptr->type(),
          idx);
  return zx::success(handle);
}

__EXPORT
zx::status<> HandleTable::Remove(zx_handle_t handle) {
  zx::status status = HandleToIndex(handle);
  if (!status.is_ok()) {
    return status.take_error();
  }
  size_t idx = status.value();

  // Pull the object out of the handle table so that we can release the handle
  // table lock before running the object's dtor. This prevents issues like
  // deadlocks if the object asserts in its dtor as a test object may do.
  fbl::RefPtr<Object> obj;
  {
    fbl::AutoLock guard(&lock_);
    obj = std::move(handles_[idx]);
  }
  ftracef("handle = 0x%x, obj = %p, type = %u, index = %zu\n", handle, obj.get(), obj->type(), idx);
  obj.reset();
  return zx::ok();
}

__EXPORT
void HandleTable::Clear() {
  fbl::AutoLock lock(&lock_);
  for (auto& e : handles_) {
    if (e) {
      e.reset();
    }
  }
}

__EXPORT
void HandleTable::Dump() {
  fbl::AutoLock lock(&lock_);
  int pos = 0;
  printf("Fake Handle Table [size: %zu]:\n", size_locked());
  for (auto& e : handles_) {
    printf("[%d] %p", pos++, e.get());
    if (e) {
      printf(" (type: %u)", static_cast<uint32_t>(e->type()));
    }
    printf("\n");
  }
}

}  // namespace fake_object
