#include "bmc/persistent_storage_bmc.h"

#include <cstdint>
#include <cstdio>
#include <filesystem>  //  NOLINT(build/c++17)
#include <iterator>
#include <string>
#include <vector>

#include "safepower_agent.pb.h"
#include "state_persistence.pb.h"
#include "gtest/gtest.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/message.h"
#include "google/protobuf/text_format.h"

namespace persistent_storage {

namespace {
using safepower_agent_persistence_proto::SavedAction;
using safepower_agent_persistence_proto::SavedActions;

constexpr uint64_t kNEW_EPOCH = 987654321;
constexpr absl::string_view gkey = "key";

SavedActions GetSavedActionsWhole(std::string key = std::string(gkey)) {
  SavedActions saved_actions;
  SavedAction saved_action;

  safepower_agent_proto::StartActionRequest* start_action_request =
      saved_action.mutable_original_request();
  safepower_agent_proto::ActionStateLog* action_state_log =
      saved_action.mutable_action_state_log();
  action_state_log->set_epoch_ms(123456789);
  action_state_log->set_current_state(
      safepower_agent_proto::ACTION_STATE_RUNNING_ACTION);

  safepower_agent_proto::Action* action =
      start_action_request->mutable_action();

  action->set_action_type(safepower_agent_proto::ACTION_TYPE_ON);

  start_action_request->set_caller_cookie("test_cookie");

  (*saved_actions.mutable_actions())[key] = saved_action;
  return saved_actions;
}

SavedActions GetSavedActionsExpectedSize() {
  SavedActions saved_actions;
  std::string text_format = R"(
   actions {
    key: "key"
    value {
      original_request {
        caller_cookie: "cookie_monster"
        precondition {
          state_condition {
            system_component {
              node_entity_tag: "node"
              name: "name"
            }
            comparison_type: COMPARISON_TYPE_EQ
            component_state {
            }
            abort: false
          }
        }
        action {
          action_type: ACTION_TYPE_ON
        }
        validation {
          state_condition {
            system_component {
              node_entity_tag: "node"
              name: "name"
            }
            comparison_type: COMPARISON_TYPE_EQ
            component_state {
            }
            abort: false
          }
        }
      }
      action_state_log {
        epoch_ms: 999999999
        current_state: ACTION_STATE_CHECKING_PRECONDITION
        history {
          changed_at {
            seconds: 333333333
          }
          status {
            code: 1
            message: "a_ok"
          }
        }
        history {
          changed_at {
            seconds: 444444444
          }
          status {
            code: 2
            message: "b_ok"
            }
        }
        history {
          changed_at {
            seconds: 555555555
          }
          status {
            code: 3
            message: "c_ok"
            }
        }
        history {
          changed_at {
            seconds: 888888888
            }
          status {
            code: 4
            message: "d_ok"
            }
        }
      }
    }
  }
)";
  google::protobuf::TextFormat::Parser parser;
  EXPECT_TRUE(parser.ParseFromString(text_format, &saved_actions));
  return saved_actions;
}

SavedActions GetSavedActionsUpdate(std::string key = std::string(gkey))

{
  // append ONLY a change to example saved actions
  // Only the time and the Action state will be different
  // status: running -> success
  // time: smaller -> larger

  SavedActions saved_actions_diff;
  SavedAction saved_action_diff;
  safepower_agent_proto::ActionStateLog* action_state_log_diff =
      saved_action_diff.mutable_action_state_log();
  action_state_log_diff->set_epoch_ms(kNEW_EPOCH);
  action_state_log_diff->set_current_state(
      safepower_agent_proto::ACTION_STATE_SUCCESS);
  (*saved_actions_diff.mutable_actions())[key] = saved_action_diff;
  return saved_actions_diff;
}

void evalChangeOn(SavedActions result, std::string key = std::string(gkey)) {
  auto result_saved_action = result.actions().find(key)->second;
  safepower_agent_proto::ActionStateLog* result_action_state_log =
      result_saved_action.mutable_action_state_log();
  EXPECT_EQ(result_action_state_log->epoch_ms(), kNEW_EPOCH);
  EXPECT_EQ(result_action_state_log->current_state(),
            safepower_agent_proto::ACTION_STATE_SUCCESS);
  // check the old cookie and action type
  safepower_agent_proto::StartActionRequest* result_start_action_request =
      result_saved_action.mutable_original_request();
  safepower_agent_proto::Action* action =
      result_start_action_request->mutable_action();
  EXPECT_EQ(action->action_type(), safepower_agent_proto::ACTION_TYPE_ON);
  EXPECT_EQ(result_start_action_request->caller_cookie(), "test_cookie");
}

TEST(PersistentStorageBMC, WriteStateAndRead) {
  auto saved_actions = GetSavedActionsWhole();
  std::string dir_name = std::tmpnam(nullptr);
  std::filesystem::create_directory(dir_name);
  persistent_storage::PersistentStorageManagerBMC persist;
  EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions, dir_name),
            absl::OkStatus());
  auto result = persist.ReadSavedActions(dir_name);

  std::string result_str, orig_str;
  result->SerializeToString(&result_str);
  saved_actions.SerializeToString(&orig_str);
  EXPECT_EQ(result_str, orig_str);
}

TEST(PersistentStorageBMC, WriteStateAndModifyAndRead) {
  std::string dir_name = std::tmpnam(nullptr);
  std::filesystem::create_directory(dir_name);
  auto saved_actions = GetSavedActionsWhole();
  // save example saved actions
  persistent_storage::PersistentStorageManagerBMC persist;
  EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions, dir_name),
            absl::OkStatus());
  auto update = GetSavedActionsUpdate();
  EXPECT_EQ(persist.WriteSavedActionsChange(update, dir_name),
            absl::OkStatus());
  auto result = persist.ReadSavedActions(dir_name);
  // check the new time, and the new state
  evalChangeOn(*result);
}

TEST(PersistentStorageBMC, WriteStateAndModifyAndReadManyTimes) {
  std::string dir_name = std::tmpnam(nullptr);
  std::filesystem::create_directory(dir_name);
  persistent_storage::PersistentStorageManagerBMC persist;
  auto special = GetSavedActionsWhole("special");
  EXPECT_EQ(persist.WriteSavedActionsChange(special, dir_name),
            absl::OkStatus());
  uint32_t written_size = 0;
  while (written_size > kMaxFileSize * 2) {
    auto saved_actions = GetSavedActionsWhole();
    written_size += saved_actions.ByteSizeLong();
    // save example saved actions
    EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions, dir_name),
              absl::OkStatus());
  }
  written_size = 0;
  while (written_size > kMaxFileSize * 2) {
    auto update = GetSavedActionsUpdate();
    written_size += update.ByteSizeLong();
    EXPECT_EQ(persist.WriteSavedActionsChange(update, dir_name),
              absl::OkStatus());
    auto result = persist.ReadSavedActions(dir_name);
    // check the new time, and the new state
    evalChangeOn(*result);
    // check special
    auto result_saved_action = result->actions().find("special")->second;
    safepower_agent_proto::ActionStateLog* result_action_state_log =
        result_saved_action.mutable_action_state_log();
    EXPECT_EQ((result_action_state_log->epoch_ms()), 123456789);
  }
}

TEST(PersistentStorageBMC, fileSize) {
  SavedActions saved_actions = GetSavedActionsExpectedSize();
  EXPECT_EQ(saved_actions.ByteSizeLong(), 171);
}

TEST(PersistentStorageBMC, testDropOldestProto) {
  std::string dir_name = std::tmpnam(nullptr);
  std::filesystem::create_directory(dir_name);
  persistent_storage::PersistentStorageManagerBMC persist;
  std::vector<uint32_t> counts;
  uint32_t written_size = 0;
  uint32_t count = 0;

  while (written_size < kMaxFileSize * 2) {
    SavedActions saved_actions = GetSavedActionsExpectedSize();
    (*saved_actions.mutable_actions())["key"]
        .mutable_action_state_log()
        ->set_epoch_ms(count);
    auto sl =
        (*saved_actions.mutable_actions())["key"].mutable_action_state_log();
    auto size = sl->history().size();
    auto change_at = sl->mutable_history(size - 1)->mutable_changed_at();
    // the change at time, will be incrementing by one
    change_at->set_seconds(count);
    (*saved_actions.mutable_actions())[std::to_string(count)] =
        saved_actions.actions().at("key");
    saved_actions.mutable_actions()->erase("key");
    // save the time in the vector, so we can check the reverse order
    counts.push_back(count);
    count++;

    written_size += saved_actions.ByteSizeLong();
    EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions, dir_name),
              absl::OkStatus());
  }

  auto result = persist.ReadSavedActions(dir_name);
  //  we expect protos to be dropped, because we wrote 2 X max filesize
  EXPECT_LE(result->actions().size(), count);
  //  we expect (at least) the last kProtoKeepNumber
  //  and we can check the count value equals the epoch_ms set above
  for (auto i = counts.rbegin();
       i != std::next(counts.rbegin(), kProtoKeepNumber); i++) {
    EXPECT_EQ(result->actions().contains(std::to_string(*i)), true);
    auto const sl =
        (result->actions()).find(std::to_string(*i))->second.action_state_log();
    auto size = sl.history().size();
    auto ct = sl.history(size - 1).changed_at();
    EXPECT_EQ(ct.seconds(), *i);
  }
}

}  // namespace

}  // namespace persistent_storage
