#include "bmc/state_monitor_bmc.h"

#include <cstdint>
#include <memory>
#include <string>

#include "bmc/daemon_context_bmc.h"
#include "bmc/redfish.h"
#include "safepower_agent.pb.h"
#include "safepower_agent_config.pb.h"
#include "state_updater.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"

namespace safepower_agent {

using safepower_agent_config::GpowerdConfig;
using safepower_agent_config::StateGatheringInfo;

StateMonitorBMC::StateMonitorBMC(
    std::shared_ptr<StateUpdater<safepower_agent_proto::SystemState>> reactor)
    : reactor_(reactor) {}

absl::Status StateMonitorBMC::BuildFromConfig(const GpowerdConfig& config) {
  for (auto& resource_to_monitor : config.state_monitor_config()) {
    if (resource_to_monitor.state_gathering_info().info_case() ==
        StateGatheringInfo::kRedfish) {
      std::string state_name = resource_to_monitor.state_name();
      std::string uri =
          resource_to_monitor.state_gathering_info().redfish().uri();
      std::string json_key =
          resource_to_monitor.state_gathering_info().redfish().json_key();
      std::string node_entity_tag =
          resource_to_monitor.system_component().node_entity_tag();
      std::string component_name =
          resource_to_monitor.system_component().name();
      uint64_t collection_interval_ms =
          resource_to_monitor.state_gathering_info().collection_interval_ms();
      auto prototype = resource_to_monitor.state_gathering_info().prototype();
      if (prototype.has_power_state() &&
          (prototype.power_state().has_state())) {
        // create bmcweb state monitor for power state
        if (!CreateRedfishUpdatePowerState(state_name, uri, json_key,
                                           collection_interval_ms,
                                           node_entity_tag, component_name)
                 .ok()) {
          LOG(ERROR) << "failed to create bmcweb state monitor for: "
                     << state_name;
          return absl::InvalidArgumentError(
              "failed to create bmcweb state monitor for: " + state_name);
        }
      } else {
        LOG(ERROR) << "update function is not supported  TODO b/372971177";
        return absl::UnimplementedError("update function is not supported ");
      }
    } else if (resource_to_monitor.state_gathering_info().info_case() ==
               StateGatheringInfo::kDbus) {
      (void)CreateDbusStateMonitor("", "", "", "", "", 1000);
    } else {
      LOG(ERROR) << "state monitor type is not supported; "
                 << resource_to_monitor.state_gathering_info().info_case();
      return absl::InvalidArgumentError(
          absl::StrCat("state monitor type is not supported: ",
                       resource_to_monitor.state_gathering_info().info_case()));
    }
  }
  return absl::OkStatus();
}

absl::Status StateMonitorBMC::CreateRedfishUpdatePowerState(
    std::string state_name, std::string uri, std::string json_key,
    int collection_interval_ms, std::string node_entity_tag,
    std::string component_name) {
  LOG(INFO) << "creating bmcweb state monitor for:" << state_name;
  LOG(INFO) << "uri: " << uri;
  LOG(INFO) << "json_key: " << json_key;
  LOG(INFO) << "collection_interval_ms: " << collection_interval_ms;

  return DaemonContextBMC::Get().scheduler().PeriodicCall(
      [state_name, uri, json_key, this, node_entity_tag, component_name] {
        Redfish::Get(uri, [state_name, uri, json_key, this, node_entity_tag,
                           component_name](absl::StatusOr<nlohmann::json> js) {
          if (!js.ok()) {
            LOG(ERROR) << "Failed to get " << uri
                       << " from BMC: " << js.status();
            return;
          }

          auto js_value = js->find(json_key);
          std::string state_str = js_value != js->end() ? *js_value : "";
          safepower_agent_proto::PowerStateSpecifier temp_power_state =
              ConvertStatePowerStringToEnum(state_str);
          const safepower_agent_proto::SystemState current_state =
              this->reactor_->state();

          safepower_agent_proto::PowerStateSpecifier last_ps =
              safepower_agent_proto::POWER_STATE_UNSPECIFIED;
          auto node_it = current_state.node_state().find(node_entity_tag);
          if (node_it != current_state.node_state().end()) {
            auto component_it =
                node_it->second.component_state().find(component_name);
            if (component_it != node_it->second.component_state().end()) {
              last_ps = component_it->second.power_state().state();
            }
          }
          if (last_ps == temp_power_state) return;
          absl::string_view last_ps_str = PowerStateSpecifier_Name(last_ps);
          absl::string_view temp_ps_str =
              PowerStateSpecifier_Name(temp_power_state);
          LOG(INFO) << absl::StrFormat(
              "state changed from: %d (%s) to: %d (%s)", last_ps, last_ps_str,
              temp_power_state, temp_ps_str);

          // add new state power state to a new system proto
          safepower_agent_proto::SystemState new_state;
          safepower_agent_proto::PowerState ps;
          ps.set_state(temp_power_state);

          safepower_agent_proto::ComponentState cs;
          *(cs.mutable_power_state()) = ps;

          safepower_agent_proto::NodeState ns;
          ns.mutable_component_state()->insert({component_name, cs});
          new_state.mutable_node_state()->insert({node_entity_tag, ns});

          reactor_->UpdateState(new_state);
        });
      },
      absl::Milliseconds(collection_interval_ms), state_name);
}

safepower_agent_proto::PowerStateSpecifier
StateMonitorBMC::ConvertStatePowerStringToEnum(absl::string_view state_str) {
  if (state_str == "On") {
    return safepower_agent_proto::POWER_STATE_ON;
  } else if (state_str == "Off") {
    return safepower_agent_proto::POWER_STATE_OFF;
  } else if (state_str == "Paused") {  // not in bmcweb
    return safepower_agent_proto::POWER_STATE_PAUSED;
  } else if (state_str == "PoweringOn") {
    return safepower_agent_proto::POWER_STATE_POWERING_ON;
  } else if (state_str == "PoweringOff") {
    return safepower_agent_proto::POWER_STATE_POWERING_OFF;
  } else {
    LOG(ERROR) << "failed to map power state string to enum: " << state_str;
    return safepower_agent_proto::POWER_STATE_UNSPECIFIED;
  }
}

absl::Status StateMonitorBMC::CreateDbusStateMonitor(
    std::string state_name, std::string dbus_path, std::string dbus_method,
    std::string dbus_interface, std::string dbus_value,
    int collection_interval_ms) {
  LOG(INFO) << "creating dbus state monitor for:" << state_name;
  LOG(INFO) << "dbus_path: " << dbus_path;
  LOG(INFO) << "dbus_method: " << dbus_method;
  LOG(INFO) << "dbus_interface: " << dbus_interface;
  LOG(INFO) << "dbus_value: " << dbus_value;
  LOG(INFO) << "collection_interval_ms: " << collection_interval_ms;
  return absl::UnimplementedError("CreateDbusStateMonitor is not implemented");
}

}  // namespace safepower_agent
