

#include "bmc/register_actions_bmc.h"

#include <cstdlib>
#include <memory>
#include <ostream>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "action_context.h"
#include "safepower_agent_config.pb.h"
#include "state_updater.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/log/log.h"

namespace safepower_agent {

namespace {

bool isASanEnabled() { return std::getenv("ASAN_OPTIONS") != nullptr; }
using safepower_agent_proto::ActionSeverity;
using safepower_agent_proto::ActionType;

TEST(RegisterActionsTest, RegisterAction) {
  if (isASanEnabled()) {
    LOG(ERROR) << "b/349393089 absl::map insert fails asan" << std::endl;
    GTEST_SKIP() << "Skipping test in ASan environment.";
    // TODO b/349393089 absl::map insert fails asan
    // Error message //https://paste.googleplex.com/6557456877748224
  }
  safepower_agent_proto::SystemState initialState;
  auto reactor =
      std::make_shared<StateUpdater<safepower_agent_proto::SystemState>>(
          std::move(initialState), true);
  auto action_context_manager =
      std::make_unique<safepower_agent::ActionContextManager>(reactor);
  safepower_agent_config::SafePowerAgentConfig safepower_agent_config;

  std::vector<std::tuple<ActionType, ActionSeverity, std::string, std::string>>
      data = {{{safepower_agent_proto::ACTION_TYPE_CYCLE},
               {safepower_agent_proto::ACTION_SEVERITY_FORCE},
               {"/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
               {"{\"ResetType\":\"ForceRestart\"}"}},
              {{safepower_agent_proto::ACTION_TYPE_CYCLE},
               {safepower_agent_proto::ACTION_SEVERITY_GRACEFUL},
               {"/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
               {"{\"ResetType\":\"GracefulRestart\"}"}}};
  for (auto [action_type, action_severity, uri, json_body] : data) {
    safepower_agent_config::ActionConfig* action_config =
        safepower_agent_config.add_action_configs();
    action_config->mutable_action()->set_action_type(action_type);
    action_config->mutable_action()->set_action_severity(action_severity);
    action_config->mutable_redfish()->set_uri(uri);
    action_config->mutable_redfish()->set_json_body(json_body);
  };

  (void)RegisterActionFromConfig(action_context_manager.get(),
                                 safepower_agent_config);

  safepower_agent_proto::GetSupportedActionsResponse response;
  action_context_manager->GetSupportedActions(response);
  EXPECT_EQ(response.actions_size(), 2);
  for (const auto& action : response.actions()) {
    EXPECT_EQ(action.action_type(), safepower_agent_proto::ACTION_TYPE_CYCLE);
    EXPECT_THAT(
        action.action_severity(),
        testing::AnyOf(safepower_agent_proto::ACTION_SEVERITY_FORCE,
                       safepower_agent_proto::ACTION_SEVERITY_GRACEFUL));
  }
}

}  // namespace

}  // namespace safepower_agent
