// 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 <lib/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;
}
