# ---------------------------| 
GN_option(GN_guards_root ${CMAKE_CURRENT_LIST_DIR})
GN_option(GN_guards_extentions ".h" ".hpp")

function(init pluginManager)
    GNP_bind(${pluginManager} "unit_processSources" ${GN_guards_root}/events.cmake)
    list(TRANSFORM GN_guards_extentions APPEND "$" OUTPUT_VARIABLE exts)
    list(JOIN exts "|" exts)
    string(REPLACE "." "\\." exts ${exts})
    GN_cache(GN_guards_exts ${exts})
    endfunction()

function(GN_guards unit)
    GNU_get(types ${unit} "srcTypes")
    foreach(type ${types})
        GNU_get(files ${unit} "srcFiles.${type}")
        foreach(file ${files})
            if (file MATCHES "${GN_guards_exts}")
                GN_guards_processHeader(${unit} ${file})
                endif()
            endforeach()
        endforeach()
    endfunction()

# ---------------------------|

function(GN_guards_processHeader unit file)
    GN_guards_guardName(name ${unit} ${file})
    GN_guards_topGuard(top ${name})
    GN_guards_botGuard(bot ${name})
    GN_guards_inject(${unit} ${file} ${top} ${bot})
    endfunction()

function(GN_guards_inject unit file top bot)
    file(READ ${file} data)
    GN_guards_checkGuards(ok "${data}")
    if (ok)
        string(APPEND re1 "^")
        string(APPEND re1 "#ifndef [A-Za-z0-9_]*\r?\n")
        string(APPEND re1 "#define [A-Za-z0-9_]*\r?\n")
        string(REGEX REPLACE "${re1}" "${top}" out "${data}")

        string(APPEND re2 "#endif *(//)?[!/ ]*[A-Za-z0-9_]*[\r\n\t ]*$")
        string(REGEX REPLACE "${re2}" "${bot}" out "${out}")
    else()
        string(APPEND out "${top}")
        string(APPEND out "${data}")
        string(APPEND out "\n")
        string(APPEND out "${bot}")
        endif()
    file(WRITE ${file} "${out}")
    endfunction()

function(GN_guards_guardName _result unit file)
    get_filename_component(name ${file} NAME)
    string(PREPEND name "${unit}__")
    string(REPLACE "." "_" name ${name})
    string(REPLACE "-" "_" name ${name})
    string(REPLACE "+" "_" name ${name})
    string(REPLACE "'" "_" name ${name})
    string(REPLACE "`" "_" name ${name})
    string(REPLACE " " ""  name ${name})
    string(TOUPPER ${name} name)
    GN_return(${name})
    endfunction()

function(GN_guards_topGuard _result name)
    set(guard "")
    string(APPEND guard "#ifndef ${name}\n")
    string(APPEND guard "#define ${name}\n")
    GN_return(${guard})
    endfunction()

function(GN_guards_botGuard _result name)
    GN_return("#endif //!${name}\n")
    endfunction()

function(GN_guards_checkGuards _result data)
    set(re "")
    string(APPEND re "^")
    string(APPEND re "#ifndef [A-Za-z0-9_]*\r?\n")
    string(APPEND re "#define [A-Za-z0-9_]*\r?\n")
    string(REGEX MATCH "${re}" matched "${data}")
    if ("${matched}" STREQUAL "")
        GN_return(off)
    else()
        GN_return(on)
        endif()
    endfunction()
