#include "tlbmc/sensors/i2c_hwmon_based_sensor.h"

#include <array>
#include <cstddef>
#include <exception>
#include <fstream>
#include <ios>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>

#include "google/protobuf/duration.pb.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/substitute.h"
#include "boost/asio.hpp"  // NOLINT: boost::asio is commonly used in BMC
#include "boost/asio/error.hpp"
#include "boost/asio/random_access_file.hpp"  // NOLINT: boost::asio is commonly used in BMC
#include "boost/filesystem.hpp"  // NOLINT: boost::filesystem is commonly used in BMC
#include "boost/filesystem/operations.hpp"
#include "boost/system/detail/error_code.hpp"  // NOLINT: boost::asio is commonly used in BMC
// NOLINTNEXTLINE: keep this so BUILD file will keep liburing
#include "liburing.h"  // IWYU pragma: keep
#include "hwmon_temp_sensor_config.pb.h"
#include "i2c_common_config.pb.h"
#include "tlbmc/hal/sysfs/i2c.h"
#include "resource.pb.h"
#include "sensor.pb.h"
#include "tlbmc/sensors/sensor.h"

namespace milotic_tlbmc {

void I2cHwmonBasedSensor::SetUpInputDeviceFile() {
  // Prod kernel doesn't support io_uring yet. To make continuous build and test
  // happy, we disable io_uring and use synchronous file read.
  // On BMC kernel, io_uring will be supported by default.
  // On cloudtop or workstation, add `--test_strategy=local` to your blaze
  // command to enable io_uring.
  try {
    // Explicitly specify the O_NONBLOCK flag to avoid blocking the input file
    // reading, needed for some kernel versions. (b/421908876)
    input_device_ = std::make_shared<boost::asio::random_access_file>(
        *io_context_, input_dev_path_,
        boost::asio::random_access_file::read_only |
            static_cast<boost::asio::random_access_file::flags>(O_NONBLOCK));
  } catch (const std::exception& e) {
    input_device_ = nullptr;
    LOG(WARNING) << "Failed to create io_uring based random_access_file for "
                 << input_dev_path_ << ": " << e.what()
                 << " . Fall back to ifstream.";
    input_file_ = std::ifstream(input_dev_path_);
  }
}

void I2cHwmonBasedSensor::SetUpInput() {
  // TODO(nanzhou): This logic should be eventually become a power signal based
  // device deletion and recreation. E.g.,
  // /sys/bus/i2c/devices/i2c-35/35-005c/hwmon/hwmon0/temp1_input
  // This also assumes the label and device mapping does not changes after
  // recreation.
  boost::filesystem::path input_dev_path(input_dev_path_);
  bool found_hwmon = false;
  boost::filesystem::path hwmon_folder =
      input_dev_path.parent_path().parent_path();
  boost::system::error_code error;
  for (const auto& entry :
       boost::filesystem::directory_iterator(hwmon_folder, error)) {
    if (error) {
      break;
    }
    // Look for something like hwmon10
    if (absl::StartsWith(entry.path().filename().string(), "hwmon")) {
      input_dev_path_ = (entry.path() / input_dev_path.filename()).string();
      found_hwmon = true;
      break;
    }
  }
  if (!found_hwmon) {
    return;
  }

  SetUpInputDeviceFile();
}

I2cHwmonBasedSensor::I2cHwmonBasedSensor(
    const std::string& input_dev_path,
    const std::shared_ptr<boost::asio::io_context>& io_context,
    SensorAttributesStatic&& sensor_attributes_static,
    std::optional<NotificationCb> on_batch_notify)
    : Sensor(std::move(sensor_attributes_static), on_batch_notify),
      input_dev_path_(input_dev_path),
      io_context_(io_context) {
  SetUpInputDeviceFile();

  input_device_usable_ = true;
}

I2cHwmonBasedSensor::~I2cHwmonBasedSensor() {
  input_device_usable_ = false;
  // We need to copy the input device and extend its lifetime because
  // `close()` will be called on it asynchronously.
  if (io_context_ && input_device_) {
    boost::asio::post(*io_context_, [input_device = input_device_] {
      input_device->close();
    });
  }
}

absl::StatusOr<boost::filesystem::path>
I2cHwmonBasedSensor::CreateDeviceAndReturnsHwmonPath(
    const I2cCommonConfig& i2c_config, std::string_view driver_name,
    const I2cSysfs& i2c_sysfs) {
  // If the device is already created, in the current implementation we don't
  // create it again.
  if (absl::Status status = i2c_sysfs.NewDevice(i2c_config, driver_name);
      !status.ok() && status.code() != absl::StatusCode::kAlreadyExists) {
    return status;
  }

  if (!i2c_sysfs.IsDevicePresent(i2c_config)) {
    return absl::InternalError(absl::Substitute(
        "Failed to find device $0 after creating it", i2c_config));
  }

  // Now the device is created, e.g.,
  // /sys/bus/i2c/devices/i2c-24/24-005c/
  boost::filesystem::path device_path =
      i2c_sysfs.Geti2cBusPath(i2c_config.bus()) /
      I2cSysfs::GetDeviceDirectoryName(i2c_config);

  if (!boost::filesystem::is_directory(device_path / "hwmon")) {
    return absl::InternalError(absl::Substitute("Failed to find hwmon under $0",
                                                device_path.string()));
  }

  boost::filesystem::path hwmon_path;
  bool found_hwmon = false;
  for (const auto& entry :
       boost::filesystem::directory_iterator(device_path / "hwmon")) {
    // Look for something like hwmon10
    if (absl::StartsWith(entry.path().filename().string(), "hwmon")) {
      found_hwmon = true;
      hwmon_path = entry.path();
      break;
    }
  }

  if (!found_hwmon) {
    return absl::InternalError(
        absl::Substitute("Failed to find hwmon for $0", device_path.string()));
  }
  return hwmon_path;
}

void I2cHwmonBasedSensor::RefreshOnceAsync(
    absl::AnyInvocable<void(const std::shared_ptr<const SensorValue>&)>
        callback) {
  std::weak_ptr<I2cHwmonBasedSensor> self = weak_from_this();
  boost::asio::post(*io_context_, [self{std::move(self)},
                                   callback = std::move(callback)]() mutable {
    std::shared_ptr<I2cHwmonBasedSensor> sensor = self.lock();
    if (!sensor || !sensor->IsInputDeviceUsable()) {
      LOG(WARNING) << "Sensor is already destroyed or input device is not "
                      "usable; cancel the refresh";
      return;
    }
    // The device might be deleted. E.g., the endpoint device lost
    // power. In this case, we will try to set up the device again and
    // bypass the refresh.
    if (!boost::filesystem::exists(sensor->GetInputDevicePath())) {
      sensor->SetUpInput();
      sensor->HandleRefreshResult(boost::asio::error::no_such_device, 0);
      if (callback) {
        callback(sensor->GetSensorData());
      }
      return;
    }
    if (sensor->GetInputDevice() != nullptr) {
      // These lines is covered on machines that have io_uring support, e.g.,
      // workstation. Add "--test_strategy=local" to your blaze command.
      // Example output with IO_URING:
      // http://sponge2/cc89fcd1-d734-4123-8652-8f3484a895e9
      sensor->GetInputDevice()->async_read_some_at(
          0, boost::asio::buffer(sensor->GetMutableReadBuffer()),
          [self, callback = std::move(callback)](
              const boost::system::error_code& error,
              size_t bytes_read) mutable {
            std::shared_ptr<I2cHwmonBasedSensor> sensor = self.lock();
            if (!sensor) {
              return;
            }
            // If the device is deleted, we will try to set up the device again
            if (error == boost::asio::error::no_such_device) {
              sensor->SetUpInput();
            }
            sensor->HandleRefreshResult(error, bytes_read);
            if (callback) {
              callback(sensor->GetSensorData());
            }
          });
      return;
    }
    sensor->GetInputFile().read(
        sensor->GetMutableReadBuffer().data(),
        static_cast<std::streamsize>(sensor->GetMutableReadBuffer().size()));
    boost::system::error_code error;
    sensor->HandleRefreshResult(error, sensor->GetConstReadBuffer().size());
    if (callback) {
      callback(sensor->GetSensorData());
    }
  });
}

}  // namespace milotic_tlbmc
