// 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 "init_task.h"

#include <zircon/status.h>

#include "coordinator.h"
#include "src/devices/lib/log/log.h"

InitTask::InitTask(fbl::RefPtr<Device> device, Completion completion)
    : Task(device->coordinator->dispatcher(), std::move(completion)), device_(std::move(device)) {}

InitTask::~InitTask() = default;

fbl::RefPtr<InitTask> InitTask::Create(fbl::RefPtr<Device> device, Completion completion) {
  return fbl::MakeRefCounted<InitTask>(std::move(device), std::move(completion));
}

void InitTask::Run() {
  LOGF(INFO, "Running init task for device %p '%s'", device_.get(), device_->name().data());

  // If the init task exists for a device, it should always run before
  // other tasks for a device.
  ZX_ASSERT(device_->state() == Device::State::kInitializing);

  // Composite and proxy devices do not implement init hooks or use init tasks.
  // If the parent is a composite device, we do not need to wait on any init task,
  // as composite devices are not created until all its fragment devices have finished
  // initializing.
  // If the parent is a proxy device, it is sufficient to wait on the init task of the
  // stored real parent (parent of the proxy device).
  ZX_ASSERT(!device_->composite());
  ZX_ASSERT(!(device_->flags & DEV_CTX_PROXY));

  if (device_->parent() && device_->parent()->state() == Device::State::kInitializing) {
    AddDependency(device_->parent()->GetActiveInit());
    return;
  }

  auto completion = [this](zx_status_t status) {
    // Only update the device state if we are not being forcibly removed.
    if (device_->state() != Device::State::kDead) {
      device_->set_state(Device::State::kActive);
    }
    if (status == ZX_OK) {
      if (!device_->wait_make_visible()) {
        status = device_->coordinator->MakeVisible(device_);
      }
    } else if (device_->state() != Device::State::kDead) {
      LOGF(ERROR, "Init task failed, scheduling removal of device %p '%s': %s", device_.get(),
           device_->name().data(), zx_status_get_string(status));
      device_->coordinator->ScheduleDriverHostRequestedRemove(device_, true /* do_unbind */);
    }
    // We still want other tasks to run even if init failed, so do not propagate errors.
    // If a driver adds multiple devices, it is possible that init tasks are scheduled
    // for both a parent and child. We will still run the child init task if the parent
    // init task fails, as drivers expect init to always run before unbind.
    // TODO(jocelyndang): consider providing the parent init failure to the child init hook.
    Complete(ZX_OK);
  };

  zx_status_t status = ZX_OK;
  if (device_->host() != nullptr) {
    status = device_->SendInit(std::move(completion));
    if (status == ZX_OK) {
      // Sent the init request, the driver_host will call our completion when ready.
      return;
    }
  }
  // No init request sent, need to call the completion now.
  completion(status);
  // Since the device didn't successfully send an CompleteInit request, it will not
  // drop our init task reference. We need to drop it now.
  device_->DropInitTask();
}
