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

#include <bind/fuchsia/hardware/i2c/cpp/bind.h>

namespace test_i2c_controller {

zx::result<> TestDa7219I2cController::Start() {
  node_.Bind(std::move(node()), dispatcher());
  i2c_server_ = std::make_shared<I2cDeviceServer>(logger_);

  // Serve the fuchsia.hardware.i2c/Device protocol to clients through the
  // fuchsia.hardware.i2c/Service wrapper.
  driver::ServiceInstanceHandler handler;
  fuchsia_hardware_i2c::Service::Handler service(&handler);
  auto result =
      service.add_device([this](fidl::ServerEnd<fuchsia_hardware_i2c::Device> request) -> void {
        I2cDeviceServer::BindDeviceClient(i2c_server_, dispatcher(), std::move(request));
      });
  if (result.is_error()) {
    return result.take_error();
  }
  result = context().outgoing()->AddService<fuchsia_hardware_i2c::Service>(std::move(handler));
  if (result.is_error()) {
    FDF_SLOG(ERROR, "Failed to add service", KV("status", result.status_string()));
    return result.take_error();
  }

  auto status = AddChild();
  if (status.status_value() != ZX_OK) {
    return status;
  }

  return zx::ok();
}

zx::result<> TestDa7219I2cController::AddChild() {
  fidl::Arena arena;

  // Offer `fuchsia.hardware.i2c.Service` to the driver that binds to the node.
  auto offers = fidl::VectorView<fuchsia_component_decl::wire::Offer>(arena, 1);
  offers[0] = driver::MakeOffer<fuchsia_hardware_i2c::Service>(arena, "default");

  // Set the properties of the node that a driver will bind to.
  auto properties = fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 2);
  properties[0] = driver::MakeEnumProperty(arena, bind_fuchsia_hardware_i2c::SERVICE,
                                           bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT);
  properties[1] = driver::MakeProperty(arena, 0x0A02 /* BIND_I2C_ADDRESS */,
                                       0x1a /* I2C address used by the DA7219 codec */);

  auto args = fuchsia_driver_framework::wire::NodeAddArgs::Builder(arena)
                  .name(arena, "i2c-child")
                  .offers(offers)
                  .properties(properties)
                  .Build();

  // Create endpoints of the `NodeController` for the node.
  auto endpoints = fidl::CreateEndpoints<fuchsia_driver_framework::NodeController>();
  if (endpoints.is_error()) {
    FDF_SLOG(ERROR, "Failed to create endpoint", KV("status", endpoints.status_string()));
    return zx::error(endpoints.status_value());
  }

  auto result = node_.sync()->AddChild(args, std::move(endpoints->server), {});
  if (!result.ok()) {
    FDF_SLOG(ERROR, "Failed to add child", KV("status", result.status_string()));
    return zx::error(result.status());
  }

  controller_.Bind(std::move(endpoints->client), dispatcher());

  return zx::ok();
}

}  // namespace test_i2c_controller

FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<test_i2c_controller::TestDa7219I2cController>);
