#include "bmc/persistent_storage_bmc.h"

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

#include "action_context.h"
#include "bmc/proto_reader.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"

namespace persistent_storage {

using safepower_agent::ActionContext;
using safepower_agent_persistence_proto::SavedAction;
using safepower_agent_persistence_proto::SavedActionAppendLog;
using safepower_agent_persistence_proto::SavedActionRecord;
using safepower_agent_persistence_proto::SavedActions;

absl::Status PersistentStorageManagerBMC::WriteSavedActionsChange(
    const SavedActions& actions) {
  return this->WriteSavedActionsChange(actions, kRWFSPath);
}

// use the data in the input arg to make several records
// if this is the first time writing the file, write the record log
// append the records to the record log, by saving them in wire format
// check the file size,
// if it is too large,
// merge, and convert to map, and back to append log
// and rewrite the file

absl::Status PersistentStorageManagerBMC::WriteSavedActionsChange(
    const SavedActions& actions, absl::string_view dir_path) {
  SavedActionAppendLog emptyAppend;
  for (const auto& i : actions.actions()) {
    SavedActionRecord* record = emptyAppend.add_records();
    record->set_action_id(i.first);
    *(record->mutable_actions()) = i.second;
  }
  std::string write_string;
  if (!emptyAppend.SerializeToString(&write_string)) {
    return absl::UnavailableError("Failed to Serialize the change record");
  }
  auto files = listFiles(dir_path);
  if (!files.ok()) {
    return files.status();
  }
  auto id = findLargestFileId(files.value());
  if (!id.ok()) {
    return id.status();
  }

  std::string file_path = MakeFileName(dir_path, id.value());

  // write the new record to the file, and close it
  // this ensures that the data is always written before the file is collated
  std::ofstream out_file;
  out_file.open(std::string(file_path), std::ios_base::app | std::ios::binary);
  out_file.write(write_string.c_str(), write_string.size());
  out_file.close();

  // if the file is too large, merge the files
  std::error_code ec;
  std::uintmax_t file_size = std::filesystem::file_size(file_path, ec);
  if (ec) {
    return absl::UnavailableError(
        absl::StrCat("Failed to get file size", ec.message()));
  }
  if (file_size > kMaxFileSize) {
    LOG(INFO) << "file size too large merging" << std::endl;
    absl::StatusOr<SavedActionAppendLog> append =
        proto_reader::ReadProto<SavedActionAppendLog>(file_path);
    if (!append.ok()) {
      return append.status();
    }

    SavedActions new_saved_actions_map;
    absl::Status status =
        this->ConvertAppendToMap(new_saved_actions_map, *append);
    if (!status.ok()) {
      return status;
    }
    // only keep the most recent protos
    auto keep_status = keepMostRecentProtos(new_saved_actions_map);
    if (!keep_status.ok()) {
      return keep_status;
    }
    // convert map to append log to save it again
    SavedActionAppendLog new_log;
    for (const auto& i : new_saved_actions_map.actions()) {
      SavedActionRecord record;
      record.set_action_id(i.first);
      *record.mutable_actions() = i.second;
      *new_log.add_records() = record;
    }

    std::ofstream out_file;

    std::string next_file = MakeFileName(dir_path, id.value() + 1);
    out_file.open(std::string(next_file), std::ios::binary);
    if (!new_log.SerializeToOstream(&out_file)) {
      return absl::InternalError("Failed to Serialize the change");
    }
    if (out_file.fail()) {
      return absl::UnavailableError("Failed to write to file");
    }
    out_file.close();
    return deleteAllFilesExceptLargest(dir_path);
  }
  return absl::OkStatus();
}

absl::Status PersistentStorageManagerBMC::ConvertAppendToMap(
    SavedActions& map, SavedActionAppendLog& log) {
  for (const auto& i : log.records()) {
    auto [it, inserted] =
        map.mutable_actions()->try_emplace(i.action_id(), i.actions());
    if (!inserted) {
      it->second.MergeFrom(i.actions());
    }
  }
  return absl::OkStatus();
}

absl::StatusOr<SavedActions> PersistentStorageManagerBMC::ReadSavedActions() {
  return this->ReadSavedActions(kRWFSPath);
}

absl::StatusOr<SavedActions> PersistentStorageManagerBMC::ReadSavedActions(
    absl::string_view dir_path) {
  auto files = listFiles(dir_path);
  if (!files.ok()) {
    return files.status();
  }
  auto id = findLargestFileId(files.value());
  if (!id.ok()) {
    return id.status();
  }
  std::string file_path = MakeFileName(dir_path, id.value());

  auto saved_actions = proto_reader::ReadProto<SavedActionAppendLog>(file_path);
  if (!saved_actions.ok()) {
    LOG(ERROR) << "Unable to read SavedActions proto file file_path:"
               << file_path << saved_actions.status();
    if (id.value() == 0) {
      return saved_actions.status();
    }
    file_path = MakeFileName(dir_path, id.value() - 1);
    LOG(ERROR) << "Trying to read older state:" << file_path;
    absl::Status original_status = saved_actions.status();
    saved_actions = proto_reader::ReadProto<SavedActionAppendLog>(file_path);
    if (!saved_actions.ok()) {
      // return the value of the original message, print the status of the
      // second read
      LOG(ERROR) << "reading older status failed, (probably file not present)"
                 << saved_actions.status();
      return original_status;
    }
  }
  SavedActions map;
  absl::Status status = (this->ConvertAppendToMap(map, *saved_actions));
  if (!status.ok()) {
    return status;
  }
  return map;
}

google::protobuf::Timestamp getChangeTime(const SavedAction& action) {
  if (!action.has_action_state_log() ||
      (action.action_state_log().history().empty())) {
    // if there is no history, return the time of the last 24 hours
    absl::Time now = absl::Now();
    absl::Time one_day_ago = now - absl::Hours(24);
    google::protobuf::Timestamp timestamp;
    timestamp.set_seconds(absl::ToUnixSeconds(one_day_ago));
    return timestamp;
  }
  return action.action_state_log().history().rbegin()->changed_at();
}

bool AtEndState(const SavedAction& action) {
  if ((!action.has_action_state_log()) ||
      !action.action_state_log().has_current_state()) {
    return false;  // if there is no state
    // we should depend on the timing logic to clear it
  }
  const safepower_agent_proto::ActionState& state =
      action.action_state_log().current_state();
  return ActionContext::IsFinalState(state);
}

// when the persistence proto is cleaned up, we need to remove the protos that
// we need to keep the most recent N protos
absl::Status PersistentStorageManagerBMC::keepMostRecentProtos(
    SavedActions& map, uint32_t keepNumber) {
  if (map.actions().size() < keepNumber) {
    LOG(WARNING) << " Assumptions about the size of the"
                 << " saved protos are wrong" << std::endl
                 << "The number of saved protos is " << map.actions().size()
                 << "less than the number we want to keep " << keepNumber;
    return absl::OkStatus();
  }

  // sort the protos by time
  std::vector<SavedActionRecord> records;
  for (const auto& i : map.actions()) {
    SavedActionRecord record;
    record.set_action_id(i.first);
    *record.mutable_actions() = i.second;
    records.push_back(record);
  }
  std::stable_sort(records.begin(), records.end(),
                   [](const SavedActionRecord& a, const SavedActionRecord& b) {
                     // if state a is not at end state
                     // and state b is at end state
                     // delete b before a, by claiming the order is correct, and
                     // returning true
                     if (!AtEndState(a.actions()) && AtEndState(b.actions())) {
                       return true;
                     }
                     auto time_a = getChangeTime(a.actions());
                     auto time_b = getChangeTime(b.actions());
                     // sort in ascending order
                     // keep tail, and delete head
                     return (time_a.seconds() < time_b.seconds()) ||
                            (time_a.seconds() == time_b.seconds() &&
                             time_a.nanos() < time_b.nanos());
                   });

  // erase the oldest protos, keeping keepNumber protos
  LOG(INFO) << "cleaning up the saved protos";
  LOG(INFO) << "current:" << records.size();
  LOG(INFO) << "keeping:" << keepNumber;
  LOG(INFO) << "deleting:" << records.size() - keepNumber;
  if (keepNumber > records.size()) {
    LOG(INFO) << "keeping all protos";
    return absl::OkStatus();
  }
  auto start = std::next(records.begin(), keepNumber + 1);
  for (auto i = start; i != records.end(); i++) {
    LOG(INFO) << " proto:" << absl::StrCat(map.actions().at(i->action_id()));
    map.mutable_actions()->erase(i->action_id());
  }
  return absl::OkStatus();
}

// find the largest file id, and return it

// the file id is a number, and the file name is in the format of
// "savedactions_1"
// "savedactions_2"
// where the largest id is the most recent file
absl::StatusOr<uint64_t> PersistentStorageManagerBMC::findLargestFileId(
    const std::vector<std::string>& files) {
  std::error_code ec;
  uint64_t largest_id = 0;
  for (const auto& entry : files) {
    std::vector<absl::string_view> file_name_parts = absl::StrSplit(entry, '_');
    if (file_name_parts.size() != 2) {
      LOG(WARNING) << "unable to parse the file name in the directory " << entry
                   << " size:" << file_name_parts.size();
      continue;
    }
    uint64_t file_id;
    if (!absl::SimpleAtoi(file_name_parts[1], &file_id)) {
      LOG(WARNING) << "unable to parse the file ID as unint64_t" << entry;
      continue;
    }
    if (file_name_parts[0] != kfileNamePrefix) {
      LOG(WARNING) << "unknown file name prefix" << entry;
      continue;
    }
    if (file_id > largest_id) {
      largest_id = file_id;
    }
  }
  return largest_id;
}

absl::StatusOr<std::vector<std::string> >
PersistentStorageManagerBMC::listFiles(absl::string_view file_path) {
  if (!std::filesystem::exists(file_path) ||
      !std::filesystem::is_directory(file_path)) {
    LOG(ERROR) << "Failed to read the directory " << file_path
               << std::filesystem::exists(file_path) << ":"
               << std::filesystem::is_directory(file_path);
    return absl::FailedPreconditionError("Failed to find the directory");
  }
  std::vector<std::string> files;
  for (const auto& entry : std::filesystem::directory_iterator(file_path)) {
    files.push_back(entry.path().filename());
  }
  return files;
}

absl::Status PersistentStorageManagerBMC::deleteAllFilesExceptLargest(
    absl::string_view file_path) {
  auto files = listFiles(file_path);
  if (!files.ok()) {
    return files.status();
  }
  auto largest = findLargestFileId(files.value());
  if (!largest.ok()) {
    return largest.status();
  }

  std::string largest_file_name =
      MakeFileName(kfileNamePrefix, largest.value());
  for (const auto& entry : files.value()) {
    if (entry == largest_file_name) {
      continue;
    }
    std::string del_path = absl::StrCat(file_path, entry);
    if (!std::filesystem::remove(del_path)) {
      LOG(ERROR) << "Failed to delete the file " << del_path;
    }
  }
  return absl::OkStatus();
}

std::string PersistentStorageManagerBMC::MakeFileName(
    absl::string_view file_path, uint64_t file_id) {
  return absl::StrCat(file_path, "/", kfileNamePrefix, "_",
                      std::to_string(file_id));
}
}  // namespace persistent_storage
