#include "persistent_storage_impl.h"

#include <unistd.h>

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

#include "action.pb.h"
#include "safepower_agent.pb.h"
#include "safepower_agent_config.pb.h"
#include "state_persistence.pb.h"
#include "utils.pb.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/message.h"

#include "test_util.h"

namespace persistent_storage {

namespace {
using safepower_agent_persistence_proto::SavedAction;
using safepower_agent_persistence_proto::SavedActions;
using borg_mgmt::node_proxy::safepower::utils::FlightRecordRequest;
using safepower_agent_persistence_proto::SavedActionRecord;
using ::testing::IsEmpty;

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

SavedActions GetSavedActionsWhole(std::string flight_id = 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");
  FlightRecordRequest test_flight_record;
  test_flight_record.set_flight_name(flight_id);
  test_flight_record.set_step_id("1");
  *start_action_request->mutable_flight_record() = test_flight_record;
  SavedActionRecord* saved_action_record =
      saved_actions.add_saved_action_records();
  *(saved_action_record->mutable_actions()) = saved_action;
  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);
  FlightRecordRequest test_flight_record;
  test_flight_record.set_flight_name(key);
  test_flight_record.set_step_id("1");
  *saved_action_diff.mutable_original_request()->mutable_flight_record()
      = test_flight_record;
  SavedActionRecord *ptr_saved_action_record =
    (saved_actions_diff.add_saved_action_records());
  *(ptr_saved_action_record->mutable_actions()) = saved_action_diff;
  return saved_actions_diff;
}

void evalChangeOn(SavedActions result, std::string key = std::string(gkey)) {
  for (const auto& i : result.saved_action_records()) {
    if (i.actions().original_request().flight_record().flight_name() == key) {
      auto result_saved_action = i.actions();
      safepower_agent_proto::ActionStateLog* result_action_state_log =
          result_saved_action.mutable_action_state_log();
      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");
    }
  }
}

std::string CreateNewTestDir() {
  static int counter = 0;
  std::string dir_path = absl::StrCat(testing::TempDir(), "/test_",
                                      counter++, "/persistent_storage");
  std::filesystem::create_directories(dir_path);
  return dir_path;
}

TEST(PersistentStorageBMC, WriteStateAndRead) {
  auto saved_actions = GetSavedActionsWhole();
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);
  EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions), absl::OkStatus());
  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());

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

TEST(PersistentStorageBMC, ReadBeforeWriteReturnsEmpty) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);
  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->saved_action_records_size(), 0);
}

TEST(PersistentStorageBMC, WriteStateAndModifyAndRead) {
  std::string dir_name = CreateNewTestDir();
  auto saved_actions = GetSavedActionsWhole();
  // save example saved actions
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);
  EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions), absl::OkStatus());
  auto update = GetSavedActionsUpdate();
  EXPECT_EQ(persist.WriteSavedActionsChange(update), absl::OkStatus());
  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  // check the new time, and the new state
  evalChangeOn(*result);
}

TEST(PersistentStorageBMC, WriteStateAndModifyAndReadManyTimes) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);
  auto special = GetSavedActionsWhole("special");
  EXPECT_EQ(persist.WriteSavedActionsChange(special), 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), absl::OkStatus());
  }
  written_size = 0;
  while (written_size < kMaxFileSize * 2) {
    auto update = GetSavedActionsUpdate();
    written_size += update.ByteSizeLong();
    EXPECT_EQ(persist.WriteSavedActionsChange(update), absl::OkStatus());
    auto result = persist.ReadSavedActions();
    ASSERT_OK(result.status());
    // check the new time, and the new state
    evalChangeOn(*result);
    // check special
    SavedAction result_special;
    for (const auto& i : result->saved_action_records()) {
      if (i.actions().original_request().flight_record().flight_name()
          == "special") {
        result_special = i.actions();
        break;
      }
    }
    EXPECT_TRUE(result_special.has_action_state_log());
    EXPECT_EQ((result_special.action_state_log().epoch_ms()), 123456789);
  }
}

TEST(PersistentStorageBMC, DropOldestProto) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);
  std::vector<uint32_t> counts;
  uint32_t written_size = 0;
  uint32_t count = 0;

  while (written_size < kMaxFileSize * 2) {
    SavedActions saved_actions;
    SavedActionRecord* record = saved_actions.add_saved_action_records();
    record->mutable_actions()->mutable_original_request()
        ->mutable_flight_record()->set_flight_name(std::to_string(count));

    record->mutable_actions()->mutable_original_request()
        ->mutable_flight_record()->set_step_id("step_id");

    record->mutable_actions()->mutable_action_state_log()->add_history()
        ->mutable_changed_at()->set_seconds(count);

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

  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  //  we expect protos to be dropped, because we wrote 2 X max filesize
  EXPECT_LT(result->saved_action_records().size(), count);

  // Create a map of flight names to change at time from the result
  absl::flat_hash_map<std::string, uint64_t> result_map;
  for (auto& record : result->saved_action_records()) {
    uint64_t time = record.actions().action_state_log().history().rbegin()->
        changed_at().seconds();
    std::string name(
        record.actions().original_request().flight_record().flight_name());
    result_map[name] = time;
  }

  //  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++) {
    const std::string flight_name = std::to_string(*i);
    ASSERT_TRUE(result_map.count(flight_name)) << "Missing flight name: ";
    EXPECT_EQ(result_map.at(flight_name), *i);
  }
}

TEST(PersistentStorageBMC, ReadWithoutPruning) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  // Ensure size limit is large enough to not trigger rotation for 15 records.
  config.set_max_file_size(kMaxFileSize * 10);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  // Write 15 unique records.
  for (int i = 0; i < 15; ++i) {
    auto actions = GetSavedActionsWhole(std::to_string(i));
    EXPECT_EQ(persist.WriteSavedActionsChange(actions), absl::OkStatus());
  }

  // Read back and verify we have exactly 15 records (not pruned to 10).
  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->saved_action_records().size(), 15);
}

TEST(PersistentStorageBMC, InitializeSavedActions) {
  std::string dir_name = CreateNewTestDir();
  std::ofstream out_file(absl::StrCat(dir_name, "/test_file"));
  ASSERT_TRUE(out_file.is_open());
  out_file.close();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);
  EXPECT_EQ(persist.InitializeSavedActions(), absl::OkStatus());
  EXPECT_EQ(std::filesystem::exists(dir_name), true);
  std::filesystem::directory_iterator it(dir_name);
  std::vector<std::filesystem::path> files(std::filesystem::begin(it),
                                           std::filesystem::end(it));
  EXPECT_THAT(files, IsEmpty());
}

void WriteActionsToFile(absl::string_view file_path,
                        const SavedActions& actions) {
  std::ofstream ofs(std::string(file_path),
                    std::ios_base::binary | std::ios_base::out);
  ASSERT_TRUE(ofs.is_open());
  ASSERT_TRUE(actions.SerializeToOstream(&ofs));
  ofs.close();
  ASSERT_FALSE(ofs.fail());
}

TEST(PersistentStorageBMC, ReadSavedActionsPreservesSequenceNumber) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto actions = GetSavedActionsWhole();
  actions.set_sequence_number(42);
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_0"), actions);

  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->sequence_number(), 42);
}

TEST(PersistentStorageBMC,
     WriteSavedActionsChangeIncrementsSequenceNumberOnRotation) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  // Force rotation on next write.
  config.set_max_file_size(1);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  // First write: goes to savedactions_0, sequence number 1.
  auto actions1 = GetSavedActionsWhole("actions1");
  ASSERT_EQ(persist.WriteSavedActionsChange(actions1), absl::OkStatus());

  // Verify active file has sequence 2 (rotated immediately because size > 1).
  auto result1 = persist.ReadSavedActions();
  ASSERT_OK(result1.status());
  EXPECT_EQ(result1->sequence_number(), 2);

  // Second write: triggers rotation to savedactions_0, sequence number 3.
  auto actions2 = GetSavedActionsWhole("actions2");
  ASSERT_EQ(persist.WriteSavedActionsChange(actions2), absl::OkStatus());

  // Verify active file is now sequence 3 and has merged content.
  auto result2 = persist.ReadSavedActions();
  ASSERT_OK(result2.status());
  EXPECT_EQ(result2->sequence_number(), 3);
  EXPECT_EQ(result2->saved_action_records_size(), 2);
}

TEST(PersistentStorageBMC, FindLargestFileIdIgnoresInvalidFileNames) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto actions1 = GetSavedActionsWhole("actions1");
  auto actions2 = GetSavedActionsWhole("actions2");
  auto actions_other = GetSavedActionsWhole("other");

  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_2"), actions1);
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_foo"),
                     actions_other);
  WriteActionsToFile(absl::StrCat(dir_name, "/notsavedactions_4"),
                     actions_other);
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions"), actions_other);
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_"), actions_other);

  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  ASSERT_EQ(result->saved_action_records_size(), 1);
  EXPECT_EQ(result->saved_action_records(0)
                .actions()
                .original_request()
                .flight_record()
                .flight_name(),
            "actions1");

  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_3"), actions2);
  result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  ASSERT_EQ(result->saved_action_records_size(), 1);
  EXPECT_EQ(result->saved_action_records(0)
                .actions()
                .original_request()
                .flight_record()
                .flight_name(),
            "actions2");
}

TEST(PersistentStorageBMC, ReadSavedActionsIgnoresInvalidFileContent) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto actions1 = GetSavedActionsWhole("actions1");
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_1"), actions1);
  // Overwrite the file with invalid content.
  std::ofstream ofs(absl::StrCat(dir_name, "/savedactions_1"),
                    std::ios_base::binary | std::ios_base::out);
  ASSERT_TRUE(ofs.is_open());
  ofs << "invalid proto content";
  ofs.close();
  ASSERT_FALSE(ofs.fail());

  auto result = persist.ReadSavedActions();
  ASSERT_FALSE(result.ok());
}

TEST(PersistentStorageBMC, ReadSavedActionsFailsIfSingleFileIsCorrupt) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  // Write a corrupt file with ID 0.
  // This ensures id.value() == 0, preventing fallback attempts.
  std::ofstream ofs(absl::StrCat(dir_name, "/savedactions_0"),
                    std::ios_base::binary | std::ios_base::out);
  ASSERT_TRUE(ofs.is_open());
  ofs << "invalid proto content";
  ofs.close();
  ASSERT_FALSE(ofs.fail());

  auto result = persist.ReadSavedActions();
  EXPECT_FALSE(result.ok());
  EXPECT_EQ(result.status().code(), absl::StatusCode::kDataLoss);
  EXPECT_THAT(result.status().message(),
              ::testing::HasSubstr("Savedactions file 0 is corrupt"));
}

TEST(PersistentStorageBMC, BootCounterAndIdPreservedAcrossPartialUpdate) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto saved_actions = GetSavedActionsWhole();
  saved_actions.set_boot_counter(42);
  saved_actions.set_boot_id("boot-id-1");

  // First write
  EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions), absl::OkStatus());

  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->boot_counter(), 42);
  EXPECT_EQ(result->boot_id(), "boot-id-1");

  // Update without setting boot_counter/boot_id
  auto update = GetSavedActionsUpdate();
  EXPECT_EQ(persist.WriteSavedActionsChange(update), absl::OkStatus());

  result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->boot_counter(), 42);
  EXPECT_EQ(result->boot_id(), "boot-id-1");
}

TEST(PersistentStorageBMC, BootCounterAndIdUpdated) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto saved_actions = GetSavedActionsWhole();
  saved_actions.set_boot_counter(42);
  saved_actions.set_boot_id("boot-id-1");

  // First write
  EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions), absl::OkStatus());

  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->boot_counter(), 42);
  EXPECT_EQ(result->boot_id(), "boot-id-1");

  // Update WITH setting boot_counter/boot_id
  saved_actions.set_boot_counter(43);
  saved_actions.set_boot_id("boot-id-2");
  EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions), absl::OkStatus());

  result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->boot_counter(), 43);
  EXPECT_EQ(result->boot_id(), "boot-id-2");
}

TEST(PersistentStorageBMC, BootCounterPreservedAcrossMerge) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  // Set small size to force merge
  config.set_max_file_size(10);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto saved_actions = GetSavedActionsWhole();
  saved_actions.set_boot_counter(100);
  saved_actions.set_boot_id("persistent-boot-id");

  // This should trigger merge immediately or on second write depending on size
  EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions), absl::OkStatus());

  // Write more to ensure multiple files / merge happens
  auto update = GetSavedActionsUpdate();
  EXPECT_EQ(persist.WriteSavedActionsChange(update), absl::OkStatus());

  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->boot_counter(), 100);
  EXPECT_EQ(result->boot_id(), "persistent-boot-id");
}

TEST(PersistentStorageBMC, BootCounterAndIdUpdatePreservesActions) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto saved_actions = GetSavedActionsWhole();
  saved_actions.set_boot_counter(10);
  saved_actions.set_boot_id("boot-id-10");

  // First write
  EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions), absl::OkStatus());

  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  ASSERT_EQ(result->saved_action_records_size(), 1);
  EXPECT_EQ(result->boot_counter(), 10);
  EXPECT_EQ(result->boot_id(), "boot-id-10");
  EXPECT_EQ(result->saved_action_records(0)
                .actions()
                .original_request()
                .flight_record()
                .flight_name(),
            "default_flight_id");

  // Update ONLY boot counter and id
  SavedActions update;
  update.set_boot_counter(20);
  update.set_boot_id("boot-id-20");

  EXPECT_EQ(persist.WriteSavedActionsChange(update), absl::OkStatus());

  result = persist.ReadSavedActions();
  ASSERT_OK(result.status());

  // Verify actions are preserved (still 1)
  ASSERT_EQ(result->saved_action_records_size(), 1);
  EXPECT_EQ(result->saved_action_records(0)
                .actions()
                .original_request()
                .flight_record()
                .flight_name(),
            "default_flight_id");

  // Verify boot info is updated
  EXPECT_EQ(result->boot_counter(), 20);
  EXPECT_EQ(result->boot_id(), "boot-id-20");
}

TEST(PersistentStorageBMC, BootCounterAndIdAdditionPreservesActions) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto saved_actions = GetSavedActionsWhole();
  // Ensure no boot info initially
  saved_actions.clear_boot_counter();
  saved_actions.clear_boot_id();

  // First write
  EXPECT_EQ(persist.WriteSavedActionsChange(saved_actions), absl::OkStatus());

  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  ASSERT_EQ(result->saved_action_records_size(), 1);
  EXPECT_EQ(result->boot_counter(), 0);
  EXPECT_TRUE(result->boot_id().empty());
  EXPECT_EQ(result->saved_action_records(0)
                .actions()
                .original_request()
                .flight_record()
                .flight_name(),
            "default_flight_id");

  // Update adding boot info only
  SavedActions update;
  update.set_boot_counter(55);
  update.set_boot_id("boot-id-55");

  EXPECT_EQ(persist.WriteSavedActionsChange(update), absl::OkStatus());

  result = persist.ReadSavedActions();
  ASSERT_OK(result.status());

  // Verify actions are preserved
  ASSERT_EQ(result->saved_action_records_size(), 1);
  EXPECT_EQ(result->saved_action_records(0)
                .actions()
                .original_request()
                .flight_record()
                .flight_name(),
            "default_flight_id");

  // Verify boot info is added
  EXPECT_EQ(result->boot_counter(), 55);
  EXPECT_EQ(result->boot_id(), "boot-id-55");
}
TEST(PersistentStorageBMC, ReadSavedActionsPermissionDenied) {
  // This test is run as root in meson, which bypasses normal filesystem
  // permissions (perms::none). Skip it if running as root.
  if (getuid() == 0) {
    GTEST_SKIP() << "Skipping permission test as root.";
  }
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  // Remove read and execute permissions from the directory.
  std::filesystem::permissions(dir_name, std::filesystem::perms::none);

  auto result = persist.ReadSavedActions();
  EXPECT_FALSE(result.ok());
  // The error comes from listFiles or exists check.
  EXPECT_EQ(result.status().code(), absl::StatusCode::kInternal);

  // Restore permissions so cleanup (TempDir removal) can work.
  std::filesystem::permissions(dir_name, std::filesystem::perms::owner_all |
                                             std::filesystem::perms::group_all);
}

TEST(PersistentStorageBMC, ReadSavedActionsNotADirectory) {
  std::string file_path = absl::StrCat(testing::TempDir(), "/not_a_dir");
  std::ofstream ofs(file_path);
  ofs << "just a file";
  ofs.close();

  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(file_path);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto result = persist.ReadSavedActions();
  EXPECT_FALSE(result.ok());
  EXPECT_EQ(result.status().code(), absl::StatusCode::kInternal);
}

TEST(PersistentStorageBMC, WriteSavedActionsChangeWriteFailure) {
  // This test is run as root in meson, which bypasses normal filesystem
  // permissions (non-writable). Skip it if running as root.
  if (getuid() == 0) {
    GTEST_SKIP() << "Skipping permission test as root.";
  }
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  // Set small size to force merge/cleanup
  config.set_max_file_size(1);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  // Create active file (savedactions_1) and inactive (savedactions_0)
  auto actions1 = GetSavedActionsWhole("actions1");
  EXPECT_EQ(persist.WriteSavedActionsChange(actions1), absl::OkStatus());

  // Now make the inactive file (savedactions_0) non-writable.
  // When we write update, it will append to savedactions_1, exceed size,
  // and try to write compressed state to savedactions_0, which should fail.
  std::filesystem::permissions(absl::StrCat(dir_name, "/savedactions_0"),
                               std::filesystem::perms::owner_read);

  auto update = GetSavedActionsUpdate();
  auto status = persist.WriteSavedActionsChange(update);
  EXPECT_FALSE(status.ok());
  EXPECT_EQ(status.code(), absl::StatusCode::kUnavailable);

  // Restore permissions for cleanup.
  std::filesystem::permissions(absl::StrCat(dir_name, "/savedactions_0"),
                               std::filesystem::perms::owner_all);
}

TEST(PersistentStorageBMC, InitializeSavedActionsDeletionFailure) {
  std::string dir_name = CreateNewTestDir();
  std::string file_path = absl::StrCat(dir_name, "/cant_delete");

  // Create a directory instead of a file.
  std::filesystem::create_directories(file_path);

  // Create a file inside it to make it non-empty.
  std::ofstream ofs(absl::StrCat(file_path, "/sub_file"));
  ofs << "content";
  ofs.close();

  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  // InitializeSavedActions iterates over files in the directory and deletes
  // them using std::filesystem::remove. If it encounters a non-empty directory,
  // remove will fail regardless of whether the user is root or not.
  auto status = persist.InitializeSavedActions();
  EXPECT_FALSE(status.ok());
  EXPECT_EQ(status.code(), absl::StatusCode::kUnavailable);
}

TEST(PersistentStorageBMC, MigrationOnWrite) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto actions1 = GetSavedActionsWhole("actions1");
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_2"), actions1);

  // Write new actions, which should trigger migration.
  auto actions2 = GetSavedActionsWhole("actions2");
  EXPECT_EQ(persist.WriteSavedActionsChange(actions2), absl::OkStatus());

  // Verify that savedactions_2 is deleted.
  EXPECT_FALSE(
      std::filesystem::exists(absl::StrCat(dir_name, "/savedactions_2")));

  // Verify that we migrated to savedactions_0.
  EXPECT_TRUE(
      std::filesystem::exists(absl::StrCat(dir_name, "/savedactions_0")));

  // Verify the content. It should contain both actions1 and actions2.
  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->saved_action_records_size(), 2);
}

TEST(PersistentStorageBMC,
     ReadFromSavedActions1WhenSavedActions0IsMissingOrCorrupt) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto actions1 = GetSavedActionsWhole("actions1");
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_1"), actions1);

  // Verify we can read when savedactions_0 is missing.
  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->saved_action_records_size(), 1);

  // Now write corrupt data to savedactions_0.
  std::ofstream ofs(absl::StrCat(dir_name, "/savedactions_0"));
  ofs << "corrupt data";
  ofs.close();

  // Verify we can still read from savedactions_1.
  result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->saved_action_records_size(), 1);
}

TEST(PersistentStorageBMC, MigrationFallbackWhenLatestOldFileIsCorrupt) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto actions1 = GetSavedActionsWhole("actions1");
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_2"), actions1);

  // Write corrupt data to savedactions_3 (latest old file).
  std::ofstream ofs(absl::StrCat(dir_name, "/savedactions_3"));
  ofs << "corrupt data";
  ofs.close();

  // Read should fallback to savedactions_2.
  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->saved_action_records_size(), 1);
  EXPECT_EQ(result->saved_action_records(0)
                .actions()
                .original_request()
                .flight_record()
                .flight_name(),
            "actions1");
}

TEST(PersistentStorageBMC, RecoverWhenOneFileIsCorrupt) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto actions0 = GetSavedActionsWhole("actions0");
  actions0.set_sequence_number(10);
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_0"), actions0);

  // Write corrupt data to savedactions_1.
  std::ofstream ofs(absl::StrCat(dir_name, "/savedactions_1"));
  ofs << "corrupt data";
  ofs.close();

  // Read should succeed using savedactions_0.
  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->saved_action_records_size(), 1);
  EXPECT_EQ(result->sequence_number(), 10);

  // Test the other way: savedactions_0 corrupt, savedactions_1 valid.
  std::ofstream ofs0(absl::StrCat(dir_name, "/savedactions_0"));
  ofs0 << "corrupt data";
  ofs0.close();

  auto actions1 = GetSavedActionsWhole("actions1");
  actions1.set_sequence_number(11);
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_1"), actions1);

  result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  EXPECT_EQ(result->saved_action_records_size(), 1);
  EXPECT_EQ(result->sequence_number(), 11);
}

TEST(PersistentStorageBMC, CorruptActiveFileDoesNotRollbackToOldFiles) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  persistent_storage::PersistentStorageManagerImpl persist(config);

  auto actions_old = GetSavedActionsWhole("old_action");
  WriteActionsToFile(absl::StrCat(dir_name, "/savedactions_2"), actions_old);

  // Create a corrupt savedactions_0.
  std::ofstream ofs(absl::StrCat(dir_name, "/savedactions_0"));
  ofs << "corrupt data";
  ofs.close();

  // Read should fail with DataLossError, and NOT rollback to savedactions_2.
  auto result = persist.ReadSavedActions();
  EXPECT_FALSE(result.ok());
  EXPECT_EQ(result.status().code(), absl::StatusCode::kDataLoss);
  EXPECT_THAT(result.status().message(),
              ::testing::HasSubstr("Savedactions file 0 is corrupt"));
}

TEST(PersistentStorageBMC, PruningKeepsNewest) {
  std::string dir_name = CreateNewTestDir();
  safepower_agent_config::PersistentStorageConfig config;
  config.set_dir_path(dir_name);
  config.set_max_file_size(1);      // Force rotation/pruning on every write
  config.set_proto_keep_number(3);  // Only keep 3 records

  persistent_storage::PersistentStorageManagerImpl persist(config);

  // Write 5 records with distinct timestamps (oldest to newest)
  for (int i = 1; i <= 5; ++i) {
    SavedActions actions;
    SavedActionRecord* record = actions.add_saved_action_records();
    record->mutable_actions()
        ->mutable_original_request()
        ->mutable_flight_record()
        ->set_flight_name(absl::StrCat("flight_", i));
    record->mutable_actions()
        ->mutable_action_state_log()
        ->add_history()
        ->mutable_changed_at()
        ->set_seconds(i * 10);  // Timestamps: 10, 20, 30, 40, 50

    ASSERT_OK(persist.WriteSavedActionsChange(actions));
  }

  // Read back and verify we kept the 3 newest records (flight_3, flight_4,
  // flight_5)
  auto result = persist.ReadSavedActions();
  ASSERT_OK(result.status());
  ASSERT_EQ(result->saved_action_records_size(), 3);

  std::vector<std::string> kept_flights;
  for (const auto& record : result->saved_action_records()) {
    kept_flights.push_back(
        record.actions().original_request().flight_record().flight_name());
  }
  EXPECT_THAT(kept_flights, ::testing::UnorderedElementsAre(
                                "flight_3", "flight_4", "flight_5"));
}

}  // namespace

}  // namespace persistent_storage
