#include <language/utils/CheckpointResumeRepository.hpp>

CheckpointResumeRepository* CheckpointResumeRepository::m_instance = nullptr;

void
CheckpointResumeRepository::checkpoint(const ASTNodeDataType& data_type,
                                       const std::string& symbol_name,
                                       const EmbeddedData& embedded_data,
                                       HighFive::File& file,
                                       HighFive::Group& checkpoint_group,
                                       HighFive::Group& symbol_table_group) const
{
  std::string data_type_name = dataTypeName(data_type);
  if (auto i_dt_function = m_data_type_checkpointing.find(data_type_name);
      i_dt_function != m_data_type_checkpointing.end()) {
    const CheckpointFunction& function = i_dt_function->second;
    function(symbol_name, embedded_data, file, checkpoint_group, symbol_table_group);
  } else {
    // LCOV_EXCL_START
    std::ostringstream error_msg;
    error_msg << "cannot find checkpointing function for type '" << rang::fgB::yellow << data_type_name
              << rang::fg::reset << "'";
    throw UnexpectedError(error_msg.str());
    // LCOV_EXCL_STOP
  }
}

EmbeddedData
CheckpointResumeRepository::resume(const ASTNodeDataType& data_type,
                                   const std::string& symbol_name,
                                   const HighFive::Group& symbol_table_group) const
{
  std::string data_type_name = dataTypeName(data_type);
  if (auto i_dt_function = m_data_type_resuming.find(data_type_name); i_dt_function != m_data_type_resuming.end()) {
    const ResumeFunction& function = i_dt_function->second;
    return function(symbol_name, symbol_table_group);
  } else {
    // LCOV_EXCL_START
    std::ostringstream error_msg;
    error_msg << "cannot find resuming function for type '" << rang::fgB::yellow << data_type_name << rang::fg::reset
              << "'";
    throw UnexpectedError(error_msg.str());
    // LCOV_EXCL_STOP
  }
}

void
CheckpointResumeRepository::create()
{
  Assert(m_instance == nullptr, "CheckpointResumeRepository was already created");
  m_instance = new CheckpointResumeRepository;
}

void
CheckpointResumeRepository::destroy()
{
  Assert(m_instance != nullptr, "CheckpointResumeRepository was not created");
  delete m_instance;
  m_instance = nullptr;
}