#ifndef AST_BACTRACE_HPP
#define AST_BACTRACE_HPP

#include <utils/PugsAssert.hpp>
#include <utils/SourceLocation.hpp>

#include <pegtl/file_input.hpp>
#include <string>
#include <vector>

class ASTNode;
class ASTBacktrace
{
 private:
  std::vector<const ASTNode*> m_stack;

  std::shared_ptr<TAO_PEGTL_NAMESPACE::file_input<>> m_file_input;

  static ASTBacktrace* m_instance;

  ASTBacktrace() = default;
  ASTBacktrace(const std::shared_ptr<TAO_PEGTL_NAMESPACE::file_input<>>& file_input);
  ~ASTBacktrace() = default;

 public:
  std::string errorMessageAt(const std::string& error_msg) const;

  SourceLocation sourceLocation() const;

  void
  push(const ASTNode* node)
  {
    m_stack.push_back(node);
  }

  void
  pop()
  {
    m_stack.pop_back();
  }

  static void create();   // for unit tests only
  static void create(const std::shared_ptr<TAO_PEGTL_NAMESPACE::file_input<>>& file_input);
  static void destroy();

  static ASTBacktrace&
  getInstance()
  {
    Assert(m_instance != nullptr);
    return *m_instance;
  }

  ASTBacktrace(const ASTBacktrace&) = delete;
  ASTBacktrace(ASTBacktrace&&)      = delete;
};

#endif   // AST_BACTRACE_HPP