#include "bmc/register_actions_bmc.h"

#include <nlohmann/json.hpp>
#include <safepower_agent.h>
#include <safepower_agent.pb.h>
#include <safepower_agent_config.pb.h>

#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_split.h"

#include "bmc/http_connection.h"

#include "action_context.h"
#include "bmc/redfish.h"

#include "boost/asio/ip/tcp.hpp"  // NOLINT
#include "boost/beast/core.hpp"  // NOLINT
#include "boost/beast/http.hpp"  // NOLINT

namespace safepower_agent {

using safepower_agent_config::SafePowerAgentConfig;

namespace beast = boost::beast;
namespace http = beast::http;

// runs after the action is called, parses the response to a status
inline absl::Status GenericRedfishParser(absl::StatusOr<nlohmann::json> js) {
  if (!js.ok()) {
    LOG(ERROR) << "BMC connection failed: " << js.status();
    return js.status();
  }
  auto extended_info = (*js)["@Message.ExtendedInfo"];
  if (extended_info.size() !=1){
    LOG(ERROR) << "redfish response has an abnormal number of message : "
        << *js;
  }
  auto info = extended_info[0];
  auto message_id = info.find("MessageId");
  if (message_id == info.end()) {
    LOG(ERROR) << "Failed to parse bmc's response to JSON: " << *js;
    return absl::InvalidArgumentError("Failed to parse bmc's response to JSON");
  }
  std::string status = *message_id;
  std::vector<std::string> v = absl::StrSplit(status, '.');
  if (v.size() >= 4 && v[4] == "Success") {
    return absl::OkStatus();
  } else {
    LOG(ERROR) << "Failed to power off :" << *message_id;
    return absl::NotFoundError("Failed to power off :"
                                 + message_id->dump());
  }
}

// runs when then action is called, perform the action
inline void GenericRedfishPowerOperation(
    absl::string_view uri, nlohmann::json body,
    std::string_view ip, uint16_t port,
    absl::AnyInvocable<void(absl::Status) &&> cb,
    const safepower_agent_proto::Action& )
  {
  LOG(INFO) << "Redfish action " << ip << ":" << port << "  " <<
      uri << " " << body;
  auto connection = std::make_shared<HttpConnection>();
  connection->PerformConnection(http::verb::post,
                               uri,
                               [callback = std::move(cb)]
                               (absl::StatusOr<nlohmann::json> js) mutable {
                                 absl::Status status = GenericRedfishParser(js);
                                 std::move(callback)(status);
                                   }, body,
                               ip, port);
  }

// runs at startup to register all actions from the config
absl::Status RegisterActionFromConfig(
    ActionContextManager* action_context_manager,
    const SafePowerAgentConfig& config)
  {
  for (const auto& action_config : config.action_configs()) {
    safepower_agent_proto::Action action_to_register = action_config.action();
    // The config will map actions to redfish (uris and body)
    // or dbus (path, method, interface, value)
    nlohmann::json body = nlohmann::json::parse(
      action_config.redfish().json_body(), /* cb */ nullptr,
        /* allow_exceptions */ false);
    if (body.is_discarded()){
      LOG(ERROR) << "Failed to parse json body: " <<
          action_config.redfish().json_body();
      return absl::InvalidArgumentError("Failed to parse json body: " +
                              action_config.redfish().json_body());
    }
    std::string uri = action_config.redfish().uri();
    uint32_t port = action_config.redfish().port();
    if (port > 65535){
      LOG(ERROR) << "Port number is invalid: " << port;
      return absl::InvalidArgumentError("Port number is invalid: " +
                                        std::to_string(port));
    }
    std::string ip = action_config.redfish().ip();
    LOG(INFO) << "registering " << action_config.action_name() << " "
       << ip << ":" << port << "  " << uri << " " << body;

    absl::Status action_status = action_context_manager->
        RegisterAction(action_to_register,
                       [uri, body, port, ip]
                       (const safepower_agent_proto::Action& a,
          absl::AnyInvocable<void(absl::Status) &&> cb) {
        GenericRedfishPowerOperation(uri, body, ip, port, std::move(cb), a);
      });

    if (!action_status.ok()){
       LOG(ERROR) << "Unable to register action :" << action_status;
       return action_status;
      }
    }
    LOG(INFO) << "All actions registered";
    return absl::OkStatus();
  }
}  // namespace safepower_agent
