# __________________________________ CONTENTS ___________________________________
#
#    This script runs following static analysis tools:
#       - cppcheck
#       - clang-tidy (currently disabled)
#    tools that are missing an executable get skipped with an appropriate
#    message recommending their installation.
#
#    Note that all of these analyzers can be ran directly from CMAKE using
#    something like this:
#       > find_program(CMAKE_CXX_CPPCHECK NAMES cppcheck)
#       > if (CMAKE_CXX_CPPCHECK)
#       >     list(
#       >         APPEND CMAKE_CXX_CPPCHECK 
#       >             "--enable=warning"
#       >             "--suppressions-list=${CMAKE_SOURCE_DIR}/CppCheckSuppressions.txt"
#       >     )
#       > endif()
#    however CMake has a tendency to make the output of those analyzers incredibly ugly,
#    interweaved with regular CMake build process and stripped of all color, which is why
#    I prefer to invoke them directly using 'compile_commands.json' generated by CMake.
#    It's also a bit more explicit about how the tools are actually invoked. 
# _______________________________________________________________________________

source bash/variables.sh
source bash/functions.sh

# ======================
# --- Run 'cppcheck' ---
# ======================

if command_exists "cppcheck" ;
then
    # Print a nice-looking header
    printf "${ansi_green}----------------------------------------${ansi_reset}\n"
    printf "${ansi_green}Found ${ansi_reset}${ansi_cyan}cppcheck${ansi_reset}${ansi_green}, running static analysis.${ansi_reset}\n"
    printf "${ansi_green}----------------------------------------${ansi_reset}\n"
    cppcheck_version=$(cppcheck --version)
    printf "${ansi_yellow}${cppcheck_version}${ansi_reset}\n"
    
    # cppcheck runs much faster if it can cache analysis data in a certain directory and then run incremental analysis,
    # since for some reason it doesn't create directories by itself we have to do it manually before providing the path
    mkdir -p "${cppcheck_cache_directory}"
    
    cppcheck --project="${directory_build}/compile_commands.json" \
        --suppressions-list="${cppcheck_suppressions_file}" \
        --cppcheck-build-dir="${cppcheck_cache_directory}" \
    # --enable=all can be added for more warning, but there is A LOT of false positives
else
    printf "${ansi_yellow}Missing ${ansi_reset}${ansi_cyan}cppcheck${ansi_reset}${ansi_yellow} static analyzer, skipping...${ansi_reset}\n"
fi

# ========================
# --- Run 'clang-tidy' ---
# ========================

# Note:
# So far clang-tidy proved to be EXTREMELY hostile to work with:
#    - no even slightly sensible way to ignore 3rd party headers
#    - meaningless spam about warnings found in system headers even though system headers are excluded,
#      the actual warnings are hidden as intended, but their amount is still printed for some reason as an
#      artifact of Clang itself that even ignores '--quiet' option
#    - no way to sensibly run on the entire project, we have to manually glob/iterate it over the right files
#    - no support for negative regex in any statements, making excluding directories impossible
#    - extremely slow analysis
#    - no way to cache the result and run analysis incrementally like in 'cppcheck'
#    - output looks uglier than it reasonably should
# so far it seems like more hassle than it is worth, which is surprising considering its popularity

# if command_exists "clang-tidy" ;
# then
#     # Print a nice-looking header
#     printf "${ansi_green}-----------------------------------------${ansi_reset}\n"
#     printf "${ansi_green}Found ${ansi_reset}${ansi_cyan}clang-tidy${ansi_reset}${ansi_green}, running static analysis.${ansi_reset}\n"
#     printf "${ansi_green}-----------------------------------------${ansi_reset}\n"
#     clangtidy_version=$(clang-tidy --version)
#     printf "${ansi_yellow}${clangtidy_version}${ansi_reset}\n"
#
#     for f in ./tests/*.cpp; do # globs like '*' are only expanded with no quotes
#         printf "${ansi_green}Analyzing file ${f}...${ansi_reset}\n"
#         clang-tidy "${f}" -p "./build/compile_commands.json" -extra-arg=-std=c++17 -header-filter=./include/UTL/*.hpp
#     done
# else
#     printf "${ansi_yellow}Missing ${ansi_reset}${ansi_cyan}clang-tidy${ansi_reset}${ansi_yellow} static analyzer, skipping...${ansi_reset}\n"
# fi