#ifndef AST_CHECKPOINTS_INFO_HPP
#define AST_CHECKPOINTS_INFO_HPP

#include <language/utils/ASTCheckpoint.hpp>
#include <utils/Exceptions.hpp>
#include <utils/PugsAssert.hpp>

#include <string>
#include <vector>

class ASTNode;

class ASTCheckpointsInfo
{
 private:
  static const ASTCheckpointsInfo* m_checkpoints_info_instance;

  std::vector<ASTCheckpoint> m_ast_checkpoint_list;

  void _findASTCheckpoint(std::vector<size_t>& location, const ASTNode& node);

  // The only place where the ASTCheckpointsInfo can be built
  friend void parser(const std::string& filename);

  // to allow special manipulations in tests
  friend class ASTCheckpointsInfoTester;

  ASTCheckpointsInfo(const ASTNode& root_node);

 public:
  size_t
  getCheckpointId(const ASTNode& node) const
  {
    for (size_t i = 0; i < m_ast_checkpoint_list.size(); ++i) {
      if (&m_ast_checkpoint_list[i].node() == &node) {
        return i;
      }
    }
    throw UnexpectedError("Could not find node");
  }

  const ASTCheckpoint&
  getASTCheckpoint(size_t checkpoint_id) const
  {
    Assert(checkpoint_id < m_ast_checkpoint_list.size());
    return m_ast_checkpoint_list[checkpoint_id];
  }

  static const ASTCheckpointsInfo& getInstance();

  ASTCheckpointsInfo() = delete;

  ~ASTCheckpointsInfo();
};

#endif   // AST_CHECKPOINTS_INFO_HPP