# ------------------------------------------------------------------------------
# MADlib Documentation
# ------------------------------------------------------------------------------

set(DOXYGEN_README_FILE "../ReadMe.txt" CACHE STRING
    "Path to ReadMe file relative to the doc directory after installation")
set(DOXYGEN_LICENSE_DIR "../../licenses" CACHE STRING
    "Path to license directory relative to the doc directory after installation")
configure_file(
    mainpage.dox.in
    "${CMAKE_CURRENT_BINARY_DIR}/mainpage.dox"
    @ONLY
)
configure_file(
    etc/DoxygenLayout.xml
    "${CMAKE_CURRENT_BINARY_DIR}/etc/DoxygenLayout.xml"
    @ONLY
)
configure_file(
    etc/header.html
    "${CMAKE_CURRENT_BINARY_DIR}/etc/header.html"
    @ONLY
)
configure_file(
    etc/madlib_extra.css
    "${CMAKE_CURRENT_BINARY_DIR}/etc/madlib_extra.css"
    @ONLY
)
file(
    COPY
    imgs/madlib.png
    DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/imgs"
)

file(
    DOWNLOAD
    "https://raw.githubusercontent.com/madlib/eigen/branches/3.2/doc/eigen_navtree_hacks.js"
    "${CMAKE_CURRENT_BINARY_DIR}/etc/eigen_navtree_hacks.js"
)

set(_DOXYGEN_INPUT_USER
    "\"${CMAKE_CURRENT_BINARY_DIR}/mainpage.dox\""
    "\"${CMAKE_SOURCE_DIR}/src/dbal\""
    "\"${CMAKE_SOURCE_DIR}/src/modules\""
    "\"${CMAKE_SOURCE_DIR}/src/ports\""
    "\"${CMAKE_SOURCE_DIR}/src/utils\""
    "\"${CMAKE_SOURCE_DIR}/methods\""
)
join_strings(DOXYGEN_INPUT_USER " " "${_DOXYGEN_INPUT_USER}")

set(_DOXYGEN_INPUT_DEVELOPER
    "\"${CMAKE_SOURCE_DIR}/src/ports/postgres/dbconnector/main.cpp\""
    ${_DOXYGEN_INPUT_USER}
)
join_strings(DOXYGEN_INPUT_DEVELOPER " " "${_DOXYGEN_INPUT_DEVELOPER}")

set(DOXYGEN_USE_MATHJAX NO CACHE BOOL "In user documentation, render LaTeX formulas using MathJax")
set(DOXYGEN_INCLUDE_PATH "\"${CMAKE_SOURCE_DIR}/src\" \"${CMAKE_SOURCE_DIR}/src/ports/postgres\"")

# Note: Type PATH implies that the value is either a relative path to
# ${CMAKE_CURRENT_BINARY_DIR} (and CMake generates the full path) or as an
# absolute path. Therefore, paths not relative to ${CMAKE_CURRENT_BINARY_DIR}
# must be of type STRING!

set(MATHJAX_INSTALLATION "${CMAKE_BINARY_DIR}/third_party/downloads/mathjax" CACHE PATH
    "Path to MathJax installation (used to clone MathJax repository; absolute or relative to \${CMAKE_BINARY_DIR}/doc)"
)
set(DOXYGEN_MATHJAX_RELPATH "${CMAKE_BINARY_DIR}/third_party/downloads/mathjax" CACHE STRING
    "Path to MathJax installation (used by Doxygen; absolute or relative to \${DOXYGEN_HTML_OUTPUT})"
)
set(DOXYGEN_OUTPUT_DEVELOPER "${CMAKE_CURRENT_BINARY_DIR}/developer" CACHE PATH
    "Base path where the documentation generated by Doxygen will be put (abolsute or relative to \${CMAKE_BINARY_DIR}/doc/etc)"
)
set(DOXYGEN_OUTPUT_USER "${CMAKE_CURRENT_BINARY_DIR}/user" CACHE PATH
    "Base path where the documentation generated by Doxygen will be put (abolsute or relative to \${CMAKE_BINARY_DIR}/doc/etc)"
)
set(DOXYGEN_HTML_OUTPUT html CACHE STRING
    "Path (relative to \${DOXYGEN_OUTPUT_<config>} where HTML docs will be put."
)

# -- Set macros for SQL/Python files -------------------------------------------

set(PORT_UC "DOXYGEN")
set(DBMS "doxygen")
set(DBMS_UC "${PORT_UC}")
set(${DBMS_UC}_VERSION_STRING "0.0.0")
set(${DBMS_UC}_VERSION_MAJOR "0")
set(${DBMS_UC}_VERSION_MINOR "0")
set(${DBMS_UC}_VERSION_PATCH "0")
set(${DBMS_UC}_ARCHITECTURE "all")
set(DBMS_FEATURES "__HAS_ORDERED_AGGREGATES__")
define_m4_macros(M4_DEFINES_CMD_LINE M4_DEFINES_CODE ${DBMS_FEATURES})


# -- Build doxysql (the SQL parser) using flex and bison -----------------------

find_package(FLEX 2.5.33)
find_package(BISON 2.4)
find_package(Doxygen)

if(FLEX_FOUND AND BISON_FOUND AND DOXYGEN_FOUND)
    # The FindFLEX module by cmake unfortunately does not cover the
    # case when FlexLexer.h is in a non-standard location.
    get_dir_name(_FLEX_BASE "${FLEX_EXECUTABLE}")
    get_dir_name(_FLEX_BASE "${_FLEX_BASE}")
    find_path(_FLEX_INCLUDE_DIR
        NAMES "FlexLexer.h"
        HINTS "${_FLEX_BASE}/include"
    )
    if(_FLEX_INCLUDE_DIR)
        include_directories(BEFORE "${_FLEX_INCLUDE_DIR}")
    endif(_FLEX_INCLUDE_DIR)

    BISON_TARGET(doxysqlParser src/sql.yy ${CMAKE_CURRENT_BINARY_DIR}/sql.parser.cc)
    FLEX_TARGET(doxysqlScanner src/sql.ll ${CMAKE_CURRENT_BINARY_DIR}/sql.scanner.cc)
    ADD_FLEX_BISON_DEPENDENCY(doxysqlScanner doxysqlParser)

    include_directories(${CMAKE_CURRENT_BINARY_DIR})
    add_executable(doxysql ${BISON_doxysqlParser_OUTPUTS}
        ${FLEX_doxysqlScanner_OUTPUTS})
    set_target_properties(doxysql PROPERTIES
        RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")


# -- Copy executable and configuration files -----------------------------------

    add_subdirectory(bin)
    add_subdirectory(etc)



# -- Update MathJax ------------------------------------------------------------

    add_custom_target(update_mathjax
        COMMAND bin/update_mathjax.sh
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
    )
    if(USE_MATHJAX)
        set(_MATHJAX_DEPENDENCY_USER update_mathjax)
    endif(USE_MATHJAX)


# -- Run doxygen ---------------------------------------------------------------

    set(_DOXYGEN_UNNEEDED_WARNINGS_FILTER egrep -v
        "warning:.*\\(@param is not found in the argument list.*kwargs\\)\$|The following parameters.*kwargs\\) are not documented\\)|parameter 'kwargs'\$")

    # Doxygen 1.7.5 does not accept absolute or relative paths for
    # CITE_BIB_FILES (this is a bug). We therefore need to copy all bib files
    # into "${CMAKE_BINARY_DIR}/doc/etc".
    add_custom_command(
        OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/etc/literature.bib"
        COMMAND ${CMAKE_COMMAND} -E copy
            "${CMAKE_SOURCE_DIR}/doc/literature.bib"
            "${CMAKE_CURRENT_BINARY_DIR}/etc/literature.bib"
        COMMENT "Copying bibliography into doxygen configuration directory."
    )

    add_custom_target(doc
        COMMAND ${DOXYGEN_EXECUTABLE} user.doxyfile | ${_DOXYGEN_UNNEEDED_WARNINGS_FILTER}
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/etc"
        DEPENDS doxysql ${_MATHJAX_DEPENDENCY_USER}
            "${CMAKE_CURRENT_BINARY_DIR}/etc/literature.bib"
        COMMENT "Generating user-level documentation..."
        VERBATIM
    )

    add_custom_target(devdoc
        COMMAND ${DOXYGEN_EXECUTABLE} developer.doxyfile | ${_DOXYGEN_UNNEEDED_WARNINGS_FILTER}
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/etc"
        DEPENDS doxysql update_mathjax
            "${CMAKE_CURRENT_BINARY_DIR}/etc/literature.bib"
        COMMENT "Generating developer documentation..."
        VERBATIM
    )

    # Copy any javascript file that is applied to the html files generated by doxygen
    add_custom_command(TARGET doc POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy
            "${CMAKE_CURRENT_BINARY_DIR}/etc/eigen_navtree_hacks.js"
            "${DOXYGEN_OUTPUT_USER}/${DOXYGEN_HTML_OUTPUT}"
    )

    # Copy any javascript file that is applied to the html files generated by doxygen
    add_custom_command(TARGET devdoc POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy
            "${CMAKE_CURRENT_BINARY_DIR}/etc/eigen_navtree_hacks.js"
            "${DOXYGEN_OUTPUT_DEVELOPER}/${DOXYGEN_HTML_OUTPUT}"
    )

# -- Install doc/user/html output directory to doc/html ------------------------

    # We specify OPTIONAL, which means it will not be an error if the user
    # documentation does not exist
    install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/user/html
        DESTINATION doc
        OPTIONAL
        COMPONENT doc
        PATTERN ".DS_Store" EXCLUDE
    )


# -- Notify user if we could not run doxygen

else(FLEX_FOUND AND BISON_FOUND AND DOXYGEN_FOUND)
    message(STATUS "Could not find recent versions of at least one of flex, "
        "bison, doxygen, or dot (part of graphviz, needed for doxygen). "
        "Documentation will not be built.")
endif(FLEX_FOUND AND BISON_FOUND AND DOXYGEN_FOUND)

# -- Add subdirectories --------------------------------------------------------

add_subdirectory(design)
