#include "bmc/http_connection.h"

#include <chrono>  // NOLINT(build/c++11)
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "bmc/daemon_context_bmc.h"
#include "bmc/mock_server.h"
#include "bmc/redfish.h"
#include "bmc/state_monitor_bmc.h"
#include "safepower_agent.pb.h"
#include "safepower_agent_config.pb.h"
#include "state_updater.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/time/time.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"

namespace safepower_agent {
namespace {

using mock_server_test::TestBoostServer;
using ::testing::StartsWith;

TEST(http, NoConnection) {
  // DO NOT start the test sever
  DaemonContextBMC context;  // only use  DaemonContextBMC::Get()

  auto my_connection = std::make_shared<HttpConnection>();
  bool callback_ran = false;
  my_connection->PerformConnection(
      (http::verb::post), "/redfish/v1/Systems/system/Actions/Power.Reset",
      [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
        ASSERT_FALSE(jres.ok());
        ASSERT_EQ(jres.status(),
                  absl::UnavailableError(absl::StrCat(
                      "Failed to connect to BMC: ", "Connection refused")));
        callback_ran = true;
      },
      {});

  DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
  EXPECT_TRUE(callback_ran);
}

TEST(http, BadAddress) {
  DaemonContextBMC context;  // only use  DaemonContextBMC::Get()
  mock_server_test::TestBoostServer my_server;
  my_server.Start(DaemonContextBMC::Get().get_io_context());

  auto my_connection = std::make_shared<HttpConnection>(absl::ZeroDuration());
  bool callback_ran = false;
  my_connection->PerformConnection(
      (http::verb::post), "/redfish/v1/Systems/system/Actions/Power.Reset",
      [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
        ASSERT_TRUE(absl::IsUnavailable(jres.status()));
        ASSERT_THAT(jres.status().message(),
                    StartsWith("Failed to connect to BMC: "));
        callback_ran = true;
      },
      {}, "240.0.0.0", 80);

  DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
  EXPECT_TRUE(callback_ran);
}

TEST(http, WriteTimeOut) {
  DaemonContextBMC context;  // only use  DaemonContextBMC::Get()
  TestBoostServer my_server;
  my_server.Start(DaemonContextBMC::Get().get_io_context());

  auto my_connection =
      std::make_shared<HttpConnection>(absl::Seconds(2), absl::ZeroDuration());
  bool callback_ran = false;
  my_connection->PerformConnection(
      (http::verb::post),
      "/redfish/v1/Systems/system/Actions/Power.Reset_never_write",
      [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
        ASSERT_FALSE(jres.ok());
        ASSERT_EQ(jres.status(),
                  absl::UnknownError("Callback error handler: The socket was "
                                     "closed due to a timeout"));
        callback_ran = true;
      },
      {});
  DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
  EXPECT_TRUE(callback_ran);
}

TEST(http, MalFormedJson) {
  DaemonContextBMC context;  // only use  DaemonContextBMC::Get()
  TestBoostServer my_server;
  my_server.Start(DaemonContextBMC::Get().get_io_context());

  auto my_connection = std::make_shared<HttpConnection>();
  bool callback_ran = false;
  my_connection->PerformConnection(
      http::verb::post,
      "/redfish/v1/Systems/system/Actions/Power.Reset_malformed",
      [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
        ASSERT_FALSE(jres.ok());
        ASSERT_EQ(jres.status(), absl::InvalidArgumentError(absl::StrCat(
                                     "Failed to parse JSON from BMC: ",
                                     mock_server_test::malformedJson)));
        callback_ran = true;
      },
      {});
  DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
  EXPECT_TRUE(callback_ran);
}

TEST(http, NotFound) {
  DaemonContextBMC context;  // only use  DaemonContextBMC::Get()
  TestBoostServer my_server;
  my_server.Start(DaemonContextBMC::Get().get_io_context());

  auto my_connection = std::make_shared<HttpConnection>();
  bool callback_ran = false;
  my_connection->PerformConnection(
      http::verb::post,
      "/redfish/v1/Systems/system/Actions/Power.Reset_NotFound",
      [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
        ASSERT_FALSE(jres.ok());
        ASSERT_EQ(jres.status(), absl::UnavailableError(
                                     "HTTP request failed with status: 404"));
        callback_ran = true;
      },
      {});
  DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
  EXPECT_TRUE(callback_ran);
}

TEST(http, GoodTest) {
  DaemonContextBMC context;  // only use  DaemonContextBMC::Get()
  auto my_server = std::make_shared<TestBoostServer>();
  my_server->Start(DaemonContextBMC::Get().get_io_context());

  auto my_connection = std::make_shared<HttpConnection>();
  bool callback_ran = false;
  my_connection->PerformConnection(
      http::verb::post, "/redfish/v1/Systems/system/Actions/Power.Reset",
      [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
        ASSERT_TRUE(jres.ok());
        callback_ran = true;
        nlohmann::json good = nlohmann::json::parse(mock_server_test::goodJson);
        ASSERT_EQ(jres.value(), good);
      },
      {});

  DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
  EXPECT_TRUE(callback_ran);
}

// redfish Tests
// redfish and http test both use mock server
// but they can not run at the same time

TEST(http, GoodGet) {
  DaemonContextBMC context;  // only use  DaemonContextBMC::Get()
  TestBoostServer my_server;
  my_server.Start(DaemonContextBMC::Get().get_io_context());
  bool callback_ran = false;
  Redfish::Get("/redfish/v1/Systems/system_get",
               [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
                 ASSERT_TRUE(jres.ok());
                 nlohmann::json good =
                     nlohmann::json::parse(mock_server_test::goodSystemGet);
                 ASSERT_EQ(jres.value(), good);
                 callback_ran = true;
               });

  DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
  EXPECT_TRUE(callback_ran);
}

TEST(http, BadGet) {
  DaemonContextBMC context;  // only use  DaemonContextBMC::Get()
  TestBoostServer my_server;
  my_server.Start(DaemonContextBMC::Get().get_io_context());
  bool callback_ran = false;
  Redfish::Get("/redfish/v1/Systems/system_NotFound",
               [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
                 ASSERT_FALSE(jres.ok());
                 ASSERT_EQ(jres.status(),
                           absl::UnavailableError(
                               "HTTP request failed with status: 404"));
                 callback_ran = true;
               });
  DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
  EXPECT_TRUE(callback_ran);
}

using safepower_agent_config::GpowerdConfig;

TEST(StateMonitorBMC, GoodBuild) {
  DaemonContextBMC context;  // only use  DaemonContextBMC::Get()
  TestBoostServer my_server;
  my_server.Start(DaemonContextBMC::Get().get_io_context());

  GpowerdConfig gpower_config;
  auto state_monitor_config = gpower_config.add_state_monitor_config();
  state_monitor_config->set_state_name("test_state");
  state_monitor_config->mutable_state_gathering_info()
      ->set_collection_interval_ms(100);
  state_monitor_config->mutable_state_gathering_info()
      ->mutable_redfish()
      ->set_uri("/redfish/v1/Systems/system/_testingPowerState");

  // if the config file has a key, it should also have the corresponding state
  std::vector<
      std::pair<std::string, safepower_agent_proto::PowerStateSpecifier>>
      json_key_to_state_name = {
          {"PowerState_On", safepower_agent_proto::POWER_STATE_ON},
          {"PowerState_Off", safepower_agent_proto::POWER_STATE_OFF},
          {"PowerState_Paused", safepower_agent_proto::POWER_STATE_PAUSED},
          {"PowerState_PoweringOn",
           safepower_agent_proto::POWER_STATE_POWERING_ON},
          {"PowerState_PoweringOff",
           safepower_agent_proto::POWER_STATE_POWERING_OFF},
          {"PowerState_UNSPECIFIED_1",
           safepower_agent_proto::POWER_STATE_UNSPECIFIED},
          {"PowerState_UNSPECIFIED_2",
           safepower_agent_proto::POWER_STATE_UNSPECIFIED},
          {"", safepower_agent_proto::POWER_STATE_UNSPECIFIED},
          {"b", safepower_agent_proto::POWER_STATE_UNSPECIFIED}};

  for (auto str_state_pair : json_key_to_state_name) {
    state_monitor_config->mutable_state_gathering_info()
        ->mutable_redfish()
        ->set_json_key(str_state_pair.first);
    state_monitor_config->set_state_name(str_state_pair.first);
    state_monitor_config->mutable_system_component()->set_node_entity_tag("cn");
    state_monitor_config->mutable_system_component()->set_name("PowerState");
    state_monitor_config->mutable_state_gathering_info()
        ->mutable_prototype()
        ->mutable_power_state()
        ->set_state(safepower_agent_proto::POWER_STATE_POWERING_OFF);
    // build a new system state
    safepower_agent_proto::SystemState initialState;
    // set default power state
    safepower_agent_proto::PowerState ps;
    ps.set_state(safepower_agent_proto::POWER_STATE_POWERING_OFF);

    safepower_agent_proto::NodeState ns;
    *(ns.mutable_power_state()) = ps;
    initialState.mutable_node_state()->insert({"cn", ns});

    auto reactor =
        std::make_shared<StateUpdater<safepower_agent_proto::SystemState>>(
            std::move(initialState), true);
    // monitor new systemd state, with specific key
    StateMonitorBMC state_monitor(reactor);
    ASSERT_EQ(state_monitor.BuildFromConfig(gpower_config), absl::OkStatus());
    DaemonContextBMC::Get().get_io_context().run_for(
        std::chrono::milliseconds(300));
    // check the state monitor updates its reactor with the correct state
    EXPECT_EQ(reactor->state().node_state().at("cn").power_state().state(),
              str_state_pair.second);
    ASSERT_EQ(DaemonContextBMC::Get().scheduler().CancelAll(),
              absl::OkStatus());
    DaemonContextBMC::Get().get_io_context().run_for(
        std::chrono::milliseconds(300));
  }

  DaemonContextBMC::Get().get_io_context().run_for(
      std::chrono::milliseconds(1000));
}

}  //  namespace
}  //  namespace safepower_agent
