include(ExternalProject)

set(AST_VISITOR_HEADER "${KLANG_INCLUDE_DIR}/AST/Visitor/Visitor.h")

file(GLOB files "${KLANG_INCLUDE_DIR}/AST/Nodes/*.h")
set(node_names "")
foreach(file ${files})
    string(REPLACE "${KLANG_INCLUDE_DIR}/AST/Nodes/" "" NODE_FILE "${file}")
    string(REPLACE ".h" "" NODE_FILE "${NODE_FILE}")
    list(APPEND node_names ${NODE_FILE})
endforeach()

file(WRITE "${AST_VISITOR_HEADER}" "#pragma once\n")
file(APPEND "${AST_VISITOR_HEADER}" "\n// This file is automatically generated. Do not edit.\n\n")
file(APPEND "${AST_VISITOR_HEADER}" "#include <any>\n\n")
file(APPEND "${AST_VISITOR_HEADER}" "#include \"AST/ASTCommon.h\"\n")
file(APPEND "${AST_VISITOR_HEADER}" "\nnamespace AST\n")
file(APPEND "${AST_VISITOR_HEADER}" "{\n")
file(APPEND "${AST_VISITOR_HEADER}" "#pragma region Forward Declarations\n")
foreach(node_name ${node_names})
    file(APPEND "${AST_VISITOR_HEADER}" "  class ${node_name};\n")
endforeach()
file(APPEND "${AST_VISITOR_HEADER}" "#pragma endregion\n\n")
file(APPEND "${AST_VISITOR_HEADER}" "  class Visitor\n")
file(APPEND "${AST_VISITOR_HEADER}" "  {\n")
file(APPEND "${AST_VISITOR_HEADER}" "  public:\n")
file(APPEND "${AST_VISITOR_HEADER}" "    virtual ~Visitor() = default;\n")
file(APPEND "${AST_VISITOR_HEADER}" "    virtual std::any VisitChildren( Node& node ) = 0;\n")
foreach(node_name ${node_names})
    file(APPEND "${AST_VISITOR_HEADER}" "    virtual std::any Visit( ${node_name}& \) = 0;\n")
endforeach()
file(APPEND "${AST_VISITOR_HEADER}" "  };\n")
file(APPEND "${AST_VISITOR_HEADER}" "}\n")