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

#include <fidl/examples.i2c.temperature/cpp/wire.h>
#include <lib/driver/component/cpp/service_client.h>

#include "constants.h"
#include "temperature_server.h"

namespace i2c_temperature {

zx::result<> I2cTemperatureDriver::Start() {
  // Connect to the I2C bus controller.
  auto channel_result = SetupI2cChannel();
  if (channel_result.is_error()) {
    return channel_result.take_error();
  }

  // Serve the examples.i2c.temperature/Device protocol to clients through the
  // examples.i2c.temperature/Service wrapper.
  examples_i2c_temperature::Service::InstanceHandler handler({
    .device = [this](fidl::ServerEnd<examples_i2c_temperature::Device> request) -> void {
        I2cTemperatureServer::BindDeviceClient(dispatcher(), &logger(), i2c_channel_,
                                               std::move(request));
      }
  });

  auto result = context().outgoing()->AddService<examples_i2c_temperature::Service>(std::move(handler));
  if (result.is_error()) {
    FDF_SLOG(ERROR, "Failed to add service", KV("status", result.status_string()));
    return result.take_error();
  }

  // Reset the sensor.
  auto write_result = i2c_channel_->Write16(kSoftResetCommand);
  if (write_result.is_error()) {
    FDF_SLOG(ERROR, "Failed to send reset command: ", KV("status", write_result.status_string()));
    return write_result.take_error();
  }

  // Initialize the driver compat service context.
  compat::Context::ConnectAndCreate(
      &context(), dispatcher(),
      fit::bind_member<&I2cTemperatureDriver::InitializeCompatService>(this));

  return zx::ok();
}

// Connect to the `fuchsia.hardware.i2c/Device` protocol offered by the parent device node.
zx::result<> I2cTemperatureDriver::SetupI2cChannel() {
  auto client_endpoint =
      driver::Connect<fuchsia_hardware_i2c::Service::Device>(*context().incoming());
  if (client_endpoint.status_value() != ZX_OK) {
    FDF_SLOG(ERROR, "Failed to setup I2cChannel", KV("status", client_endpoint.status_string()));
    return client_endpoint.take_error();
  }

  auto i2c_client = fidl::WireClient(std::move(*client_endpoint), dispatcher());
  i2c_channel_ = std::make_shared<I2cChannel>(std::move(i2c_client));
  return zx::ok();
}

// Initialize the driver compat context and export `examples.i2.temperature/Service` to
// devfs.
void I2cTemperatureDriver::InitializeCompatService(
    zx::result<std::shared_ptr<compat::Context>> compat_result) {
  if (!compat_result.is_ok()) {
    FDF_SLOG(ERROR, "Failed to create compat context.",
             KV("status", compat_result.status_string()));
    node().reset();
    return;
  }
  compat_context_ = std::move(*compat_result);

  auto service_path = std::string(examples_i2c_temperature::Service::Name) + "/" +
                      component::kDefaultInstance + "/" +
                      examples_i2c_temperature::Service::Device::Name;
  auto status = compat_context_->devfs_exporter().ExportSync(
      service_path, compat_context_->TopologicalPath(name()), fuchsia_device_fs::ExportOptions());
  if (status != ZX_OK) {
    FDF_SLOG(ERROR, "Failed to export to devfs.", KV("status", zx_status_get_string(status)));
    node().reset();
    return;
  }
}

}  // namespace i2c_temperature

FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<i2c_temperature::I2cTemperatureDriver>);
