#include "tlbmc/sensors/virtual_sensor.h"

#include <chrono>  // NOLINT
#include <memory>
#include <optional>
#include <string>
#include <utility>

#include "absl/container/flat_hash_map.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/str_cat.h"
#include "virtual_sensor_config.pb.h"
#include "tlbmc/expression/expression.h"
#include "resource.pb.h"
#include "sensor.pb.h"
#include "tlbmc/sensors/sensor.h"
#include "tlbmc/time/time.h"

namespace milotic_tlbmc {

absl::StatusOr<std::shared_ptr<VirtualSensor>> VirtualSensor::Create(
    const VirtualSensorConfig& config,
    const std::shared_ptr<boost::asio::io_context>& io_context,
    const absl::flat_hash_map<std::string, std::shared_ptr<Sensor>>&
        sensors_map,
    std::unique_ptr<Expression> expression,
    std::optional<NotificationCb> on_batch_notify) {
  return std::make_shared<VirtualSensor>(
      Token(), config.name(), config.unit(), config.entity_common_config(),
      config.thresholds(), config.reading_ranges(), sensors_map,
      std::move(expression), io_context, on_batch_notify);
}

VirtualSensor::VirtualSensor(
    Token token, const std::string& sensor_name, SensorUnit sensor_unit,
    const EntityCommonConfig& entity_common_config,
    const ThresholdConfigs& threshold_configs,
    const ReadingRangeConfigs& reading_range_configs,
    const absl::flat_hash_map<std::string, std::shared_ptr<Sensor>>&
        sensors_map,
    std::unique_ptr<Expression> expression,
    const std::shared_ptr<boost::asio::io_context>& io_context,
    std::optional<NotificationCb> on_batch_notify)
    : Sensor(CreateStaticAttributes(sensor_name, sensor_unit,
                                    /*i2c_common_config=*/{},
                                    entity_common_config, reading_range_configs,
                                    /*reading_transform_config=*/{}),
             threshold_configs, on_batch_notify),
      io_context_(io_context),
      sensors_map_(sensors_map),
      expression_(std::move(expression)),
      sensor_name_(sensor_name) {}

void VirtualSensor::RefreshOnceAsync(
    absl::AnyInvocable<void(const std::shared_ptr<const SensorValue>&)>
        callback) {
  std::weak_ptr<VirtualSensor> self = shared_from_this();
  boost::asio::post(*io_context_, [self(std::move(self)),
                                   callback(std::move(callback))]() mutable {
    std::shared_ptr<VirtualSensor> sensor = self.lock();
    if (!sensor) {
      LOG(WARNING) << "Sensor is destroyed; cancel the refresh.";
      return;
    }
    std::chrono::steady_clock::time_point last_refresh_start_time =
        sensor->GetLastRefreshStartTime();
    if (last_refresh_start_time !=
        std::chrono::steady_clock::time_point::min()) {
      sensor->UpdateSoftwarePollingStartMetrics(
          std::chrono::steady_clock::now() - last_refresh_start_time);
    }
    sensor->SetLastRefreshStartTime(std::chrono::steady_clock::now());

    // Get the sensor value
    absl::StatusOr<double> sensor_value = sensor->GetSensorValue();

    if (!sensor_value.ok()) {
      State state;
      state.set_status(STATUS_STALE);
      state.set_status_message(
          absl::StrCat("Failed to read sensor value with error: ",
                       sensor_value.status().message()));
      sensor->UpdateState(std::move(state));
      if (callback) {
        callback(sensor->GetSensorData());
      }
      DLOG(INFO) << "VirtualSensor::RefreshOnceAsync failed: "
                 << sensor->sensor_name_ << " " << sensor_value.status();
    } else {
      SensorValue sensor_data;
      // milliseconds to timestamp
      *sensor_data.mutable_timestamp() = Now();
      sensor_data.set_reading(static_cast<double>(*sensor_value));
      DLOG(INFO) << "VirtualSensor::RefreshOnceAsync success: "
                 << sensor->sensor_name_ << " " << sensor_data.reading();
      sensor->StoreSensorData(
          std::make_shared<const SensorValue>(std::move(sensor_data)));
      State state;
      state.set_status(STATUS_READY);
      sensor->UpdateState(std::move(state));

      if (callback) {
        callback(sensor->GetSensorData());
      }
    }
    std::chrono::steady_clock::time_point last_refresh_end_time =
        sensor->GetLastRefreshEndTime();
    if (last_refresh_end_time != std::chrono::steady_clock::time_point::min()) {
      sensor->UpdateSoftwarePollingEndMetrics(std::chrono::steady_clock::now() -
                                              last_refresh_end_time);
    }
    sensor->SetLastRefreshEndTime(std::chrono::steady_clock::now());
  });
}

absl::StatusOr<double> VirtualSensor::GetSensorValue() {
  absl::flat_hash_map<std::string, double> sensor_readings_map;
  for (const auto& [sensor_name, sensor] : sensors_map_) {
    if (sensor == nullptr) {
      return absl::InvalidArgumentError(
          absl::StrCat("Sensor ", sensor_name, " is missing"));
    }
    const std::shared_ptr<const SensorValue> sensor_data =
        sensor->GetSensorData();
    if (sensor_data == nullptr) {
      return absl::InvalidArgumentError("Sensor data is null");
    }
    sensor_readings_map[sensor_name] = sensor_data->reading();
  }
  return expression_->Evaluate(sensor_readings_map);
}

}  // namespace milotic_tlbmc
