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

#include <endian.h>
#include <lib/driver/component/cpp/structured_logger.h>

#include "constants.h"

namespace i2c_temperature {

// Static
// Handle incoming connection requests from FIDL clients
fidl::ServerBindingRef<examples_i2c_temperature::Device> I2cTemperatureServer::BindDeviceClient(
    async_dispatcher_t* dispatcher, driver::Logger* logger, std::weak_ptr<I2cChannel> i2c_channel,
    fidl::ServerEnd<examples_i2c_temperature::Device> request) {
  // Bind each connection request to the shared instance.
  auto server_impl = std::make_unique<I2cTemperatureServer>(logger, i2c_channel);
  return fidl::BindServer(dispatcher, std::move(request), std::move(server_impl),
                          std::mem_fn(&I2cTemperatureServer::OnUnbound));
}

// This method is called when a server connection is torn down.
void I2cTemperatureServer::OnUnbound(fidl::UnbindInfo info,
                                     fidl::ServerEnd<examples_i2c_temperature::Device> server_end) {
  if (info.is_peer_closed()) {
    FDF_LOG(DEBUG, "Client disconnected");
  } else if (!info.is_user_initiated()) {
    FDF_LOG(ERROR, "Client connection unbound: %s", info.status_string());
  }
}

// Protocol method in `examples.i2c.temperature` to return the current temperature
void I2cTemperatureServer::ReadTemperature(ReadTemperatureCompleter::Sync& completer) {
  auto channel = i2c_channel_.lock();
  if (!channel) {
    FDF_LOG(ERROR, "Unable to access I2C channel.");
    completer.ReplyError(ZX_ERR_BAD_STATE);
    return;
  }

  // Send a command to start the measurement.
  auto status = channel->Write16(kStartMeasurementCommand);
  if (status.is_error()) {
    FDF_SLOG(ERROR, "Failed to send measurement command: ", KV("status", status.status_string()));
    completer.ReplyError(status.status_value());
    return;
  }

  // Read the temperature measurement.
  auto temp_result = channel->Read16();
  if (temp_result.is_error()) {
    FDF_SLOG(ERROR, "Failed to read temperature: ", KV("status", temp_result.status_string()));
    completer.ReplyError(temp_result.status_value());
    return;
  }

  auto temp_value = static_cast<uint32_t>(temp_result.value());
  FDF_SLOG(INFO, "Received temperature: ", KV("value", temp_value));
  return completer.ReplySuccess(temp_value);
}

// Protocol method in `examples.i2c.temperature` to reset the temperature sensor
void I2cTemperatureServer::ResetSensor(ResetSensorCompleter::Sync& completer) {
  auto channel = i2c_channel_.lock();
  if (!channel) {
    FDF_LOG(ERROR, "Unable to access I2C channel.");
    completer.ReplyError(ZX_ERR_BAD_STATE);
    return;
  }

  // Send the reset command.
  auto result = channel->Write16(kSoftResetCommand);
  if (result.is_error()) {
    FDF_SLOG(ERROR, "Failed to send reset command: ", KV("status", result.status_string()));
    completer.ReplyError(result.status_value());
    return;
  }
}

}  // namespace i2c_temperature
