// Copyright 2022 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 "composite_sample.h"

#include <fidl/fuchsia.driver.compat/cpp/wire.h>
#include <lib/driver2/record_cpp.h>

namespace composite_sample {

// static
zx::status<std::unique_ptr<CompositeSampleDriver>> CompositeSampleDriver::Start(
    fuchsia_driver_framework::wire::DriverStartArgs &start_args, fdf::UnownedDispatcher dispatcher,
    fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
    driver::Logger logger) {
  auto driver = std::make_unique<CompositeSampleDriver>(
      dispatcher->async_dispatcher(), std::move(node), std::move(ns), std::move(logger));
  auto result = driver->Run(dispatcher->async_dispatcher(), std::move(start_args.outgoing_dir()));
  if (result.is_error()) {
    return result.take_error();
  }

  return zx::ok(std::move(driver));
}

zx::status<> CompositeSampleDriver::Run(async_dispatcher *dispatcher,
                                        fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir) {
  auto result = PrintTopologicalPath("acpi-GFBY");
  if (result.is_error()) {
    FDF_SLOG(ERROR, "Failed to print topological path for \"acpi-GFBY\"",
             KV("status", result.status_string()));
    return result.take_error();
  }

  result = PrintTopologicalPath("acpi-GFRT");
  if (result.is_error()) {
    FDF_SLOG(ERROR, "Failed to print topological path for \"acpi-GFBY\"",
             KV("status", result.status_string()));
    return result.take_error();
  }

  return outgoing_.Serve(std::move(outgoing_dir));
}

// Print the topological path for a given parent device node.
zx::status<> CompositeSampleDriver::PrintTopologicalPath(std::string_view name) {
  // Connect to the parent device node.
  auto result = ns_.OpenService<fuchsia_driver_compat::Service>(name);
  if (result.is_error()) {
    FDF_SLOG(ERROR, "Failed to open service", KV("status", result.status_string()));
    return result.take_error();
  }

  auto parent = result.value().connect_device();
  if (parent.is_error()) {
    FDF_SLOG(ERROR, "Failed to connect to parent", KV("status", parent.status_string()));
    return parent.take_error();
  }

  // Retrieve the path of the device node from the `fuchsia.driver.compat` service
  auto path_result = fidl::WireCall<fuchsia_driver_compat::Device>(*parent)->GetTopologicalPath();
  if (!path_result.ok()) {
    FDF_SLOG(ERROR, "Failed to get topological path", KV("status", result.status_string()));
    return zx::error(path_result.status());
  }

  std::string path(path_result->path.get());
  FDF_SLOG(INFO, "Topological path ", KV("path", path.c_str()));

  return zx::ok();
}

}  // namespace composite_sample

FUCHSIA_DRIVER_RECORD_CPP_V1(composite_sample::CompositeSampleDriver);
