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

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

namespace fio = fuchsia_io;

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<fio::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));
}

zx::status<> CompositeSampleDriver::PrintTopologicalPath(std::string_view name) {
  // Connect to parent.
  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();
  }

  auto path_result = fidl::WireCall(*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);
