#ifndef WHILE_PROCESSOR_HPP
#define WHILE_PROCESSOR_HPP

#include <language/ast/ASTNode.hpp>
#include <language/node_processor/INodeProcessor.hpp>
#include <language/utils/SymbolTable.hpp>

class WhileProcessor final : public INodeProcessor
{
 private:
  ASTNode& m_node;

 public:
  DataVariant
  execute(ExecutionPolicy& exec_policy)
  {
    ExecutionPolicy exec_until_jump;
    while ([&]() {
      return static_cast<bool>(std::visit(
        [](const auto& value) -> bool {
          using T = std::decay_t<decltype(value)>;
          if constexpr (std::is_arithmetic_v<T>) {
            return value;
          } else {
            return false;   // LCOV_EXCL_LINE (unreachable: only there for compilation purpose)
          }
        },
        m_node.children[0]->execute(exec_policy)));
    }()) {
      m_node.children[1]->execute(exec_until_jump);
      if (not exec_until_jump.exec()) {
        if (exec_until_jump.jumpType() == ExecutionPolicy::JumpType::break_jump) {
          break;
        } else if (exec_until_jump.jumpType() == ExecutionPolicy::JumpType::continue_jump) {
          exec_until_jump = ExecutionPolicy{};   // getting ready for next loop traversal
        }
      }
    }

    m_node.children[1]->m_symbol_table->clearValues();
    return {};
  }

  WhileProcessor(ASTNode& node) : m_node{node} {}
};

#endif   // WHILE_PROCESSOR_HPP