#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 "parse_text_proto.h"
#include "safepower_agent.pb.h"
#include "safepower_agent_config.pb.h"
#include "state_updater.h"
#include "one/offline_node_entities.pb.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"

#include "test_util.h"

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 ::production_msv::node_entities_proto::OfflineNodeEntityInformation;
using ::safepower_agent_config::GpowerdConfig;
TEST(StateMonitorBMC, GoodBuild) {
  DaemonContextBMC context;  // only use  DaemonContextBMC::Get()
  ASSERT_OK_AND_ASSIGN(auto offline_node_entities,
                       ParseTextProto<OfflineNodeEntityInformation>(R"pb(
                         entity_tag: "host-control-node"
                       )pb"));
  context.set_offline_node_entities(offline_node_entities);
  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
