// 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 "test-driver-child.h"

#include <ddk/debug.h>
#include <ddktl/device.h>
#include <fbl/alloc_checker.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>

void TestLifecycleDriverChild::DdkRelease() {
  // Release the reference now that devmgr no longer has a pointer to this object.
  __UNUSED bool dummy = Release();
}

void TestLifecycleDriverChild::AsyncRemove(fit::function<void()> callback) {
  async_remove_ = true;
  unbind_callback_ = std::move(callback);
  DdkAsyncRemove();
}

void TestLifecycleDriverChild::CompleteUnbind() { unbind_txn_->Reply(); }

zx_status_t TestLifecycleDriverChild::Create(zx_device_t* parent, bool complete_init,
                                             zx_status_t init_status,
                                             fbl::RefPtr<TestLifecycleDriverChild>* out_device) {
  fbl::AllocChecker ac;
  auto device =
      fbl::MakeRefCountedChecked<TestLifecycleDriverChild>(&ac, parent, complete_init, init_status);
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }

  *out_device = device;

  zx_status_t status = device->DdkAdd("ddk-lifecycle-test-child");
  if (status != ZX_OK) {
    out_device->reset();
    return status;
  }
  // Hold a reference while devmgr has a pointer to this object.
  device->AddRef();
  return ZX_OK;
}

zx_status_t TestLifecycleDriverChild::DdkOpen(zx_device_t** dev_out, uint32_t flags) {
  return (new InstanceDevice(zxdev()))->Add(dev_out);
}

void TestLifecycleDriverChild::DdkInit(ddk::InitTxn txn) {
  if (complete_init_) {
    txn.Reply(init_status_);
    replied_to_init_ = true;
  } else {
    init_txn_ = std::move(txn);
  }
}

void TestLifecycleDriverChild::DdkUnbind(ddk::UnbindTxn txn) {
  ZX_ASSERT(!init_txn_);
  if (async_remove_) {
    unbind_txn_ = std::move(txn);
    (*unbind_callback_)();
    return;
  }
  txn.Reply();
}

zx_status_t TestLifecycleDriverChild::CompleteInit() {
  if (replied_to_init_) {
    zxlogf(ERROR, "Already replied to init");
    return ZX_ERR_BAD_STATE;
  }
  if (!init_txn_) {
    // The init hook has not been called yet.
    complete_init_ = true;
    return ZX_OK;
  }
  init_txn_->Reply(init_status_);
  init_txn_ = std::nullopt;
  replied_to_init_ = true;
  return ZX_OK;
}
