#ifndef IF_PROCESSOR_HPP
#define IF_PROCESSOR_HPP

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

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

 public:
  DataVariant
  execute(ExecutionPolicy& exec_policy)
  {
    const bool is_true = static_cast<bool>(std::visit(   // LCOV_EXCL_LINE (false negative)
      [](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)));
    if (is_true) {
      Assert(m_node.children[1] != nullptr);
      m_node.children[1]->execute(exec_policy);
      if (m_node.children[1]->m_symbol_table != m_node.m_symbol_table)
        m_node.children[1]->m_symbol_table->clearValues();

    } else {
      if (m_node.children.size() == 3) {
        // else statement
        Assert(m_node.children[2] != nullptr);
        m_node.children[2]->execute(exec_policy);
        if (m_node.children[2]->m_symbol_table != m_node.m_symbol_table)
          m_node.children[2]->m_symbol_table->clearValues();
      }
    }

    Assert(m_node.children[0]->m_symbol_table == m_node.m_symbol_table);
    return {};
  }

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

#endif   // IF_PROCESSOR_HPP