# As this application is build during the SDK configuration, it cannot use the camitk_application macro
# Everything has to be set up manually
set(APPLICATION_NAME_CMAKE "EXTENSIONGENERATOR")
set(APPLICATION_NAME "extensiongenerator")

if(NOT APPLICATION_${APPLICATION_NAME_CMAKE}_INTERNAL)
    # add option to enable/disable this extension and set it to true by default
    # Building the extension can be disabled by giving the argument DISABLED to the macro
    # or by passing the flag -D${TYPE_EXTENSION_CMAKE}_${APPLICATION_NAME_CMAKE}_DISABLED:BOOL=TRUE
    if(${APPLICATION_NAME_CMAKE}_DISABLED)
        set(APPLICATION_${APPLICATION_NAME_CMAKE}_ENABLED FALSE)
    else()
        set(APPLICATION_${APPLICATION_NAME_CMAKE}_ENABLED TRUE)
    endif()
    set(APPLICATION_${APPLICATION_NAME_CMAKE} ${APPLICATION_${APPLICATION_NAME_CMAKE}_ENABLED} CACHE BOOL "Build application ${APPLICATION_NAME}")
    set(APPLICATION_${APPLICATION_NAME_CMAKE}_INTERNAL TRUE CACHE INTERNAL "Is variable APPLICATION_${APPLICATION_NAME} already created?")
endif()

set(APPLICATION_TARGET_NAME application-${APPLICATION_NAME})

message(STATUS "Building application ${APPLICATION_NAME}")

# auto moc
set(CMAKE_AUTOMOC ON)

# includes
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CAMITK_INCLUDE_DIRECTORIES})
# to get the current CamiTK version
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CurrentCamiTKVersion.h.in ${CMAKE_CURRENT_BINARY_DIR}/CurrentCamiTKVersion.h)

# sources
set(${APPLICATION_NAME}_SOURCES main.cpp CommandLineOptions.cxx CommandLineOptions.hxx)

add_executable(${APPLICATION_TARGET_NAME} ${${APPLICATION_NAME}_SOURCES})

target_link_directories(${APPLICATION_TARGET_NAME} PUBLIC ${CAMITK_LINK_DIRECTORIES})

# dependencies: Qt and extensiongenerator library
# library dependency
target_link_libraries(${APPLICATION_TARGET_NAME} PRIVATE ${CAMITK_EXTENSIONGENERATOR_LIBRARY} ${CAMITK_QT_LIBRARIES})

# build dependencies
add_dependencies(${APPLICATION_TARGET_NAME} ${CAMITK_EXTENSIONGENERATOR_TARGET_LIB_NAME})
# add the dependency to the core automoc target
set_property(TARGET ${APPLICATION_TARGET_NAME} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS ${CAMITK_EXTENSIONGENERATOR_TARGET_LIB_NAME})

# OUTPUT NAME
if (MSVC)
set_target_properties(${APPLICATION_TARGET_NAME}
                      PROPERTIES OUTPUT_NAME camitk-${APPLICATION_NAME}
                      DEBUG_POSTFIX ${CAMITK_DEBUG_POSTFIX})
else()
set_target_properties(${APPLICATION_TARGET_NAME}
                      PROPERTIES OUTPUT_NAME camitk-${APPLICATION_NAME}
)
endif()

# OUTPUT DIRECTORY LOCATION
# always in bin folder
set_target_properties(${APPLICATION_TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CAMITK_BUILD_BIN_DIR}
                                                            RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_BIN_DIR}
                                                            RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_BIN_DIR}
)

# Temporary take multiarch into account for packaging during nested cmake run
if (CAMITK_HOST_MULTIARCH)
    target_link_directories(${APPLICATION_TARGET_NAME} PRIVATE ${CAMITK_BUILD_PUBLIC_LIB_DIR}/${CAMITK_HOST_MULTIARCH})
endif()

# FOLDER INSTALLATION
message(STATUS "Installing application ${APPLICATION_TARGET_NAME} in ${CMAKE_INSTALL_BINDIR}")        
install(TARGETS ${APPLICATION_TARGET_NAME}
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
        COMPONENT ${APPLICATION_TARGET_NAME}
)

# cdash organisation
camitk_register_subproject(APPLICATION ${APPLICATION_TARGET_NAME} DEPENDENCIES library-camitkcore ${CEP_LIBRARIES_DEPENDENCY_LIST})

if(UNIX)
    # Man page installation
    set(${APPLICATION_NAME_CMAKE}_MAN_PAGE ${CMAKE_CURRENT_SOURCE_DIR}/resources/camitk-${APPLICATION_NAME}.1)
    if (EXISTS ${${APPLICATION_NAME_CMAKE}_MAN_PAGE})
        message(STATUS "Found man page for ${APPLICATION_TARGET_NAME}")
        install(FILES ${${APPLICATION_NAME_CMAKE}_MAN_PAGE}
                DESTINATION ${CAMITK_APPLICATION_MAN_INSTALL_DIR}
        )
    else()
        # check if .in exists
        if (EXISTS "${${APPLICATION_NAME_CMAKE}_MAN_PAGE}.in")
            message(STATUS "Found man page configuration file for ${APPLICATION_TARGET_NAME}")
            install(CODE "message(STATUS \"Updating ${APPLICATION_NAME} man page (version ${CAMITK_VERSION_MAJOR}.${CAMITK_VERSION_MINOR} as of ${CURRENT_DATE})\")")
            # set variable in sub-cmake shell
            install(CODE "set(APPLICATION_NAME ${APPLICATION_NAME})")
            install(CODE "set(CURRENT_DATE ${CURRENT_DATE})")
            install(CODE "set(CAMITK_VERSION_MAJOR ${CAMITK_VERSION_MAJOR})")
            install(CODE "set(CAMITK_VERSION_MINOR ${CAMITK_VERSION_MINOR})")
            # remove previous version
            install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_CURRENT_BINARY_DIR}/camitk-${APPLICATION_NAME}.1)")
            # configure current version
            install(CODE "configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/camitk-${APPLICATION_NAME}.1.in ${CMAKE_CURRENT_BINARY_DIR}/camitk-${APPLICATION_NAME}.1 @ONLY)")
            # install file
            install(FILES ${CMAKE_CURRENT_BINARY_DIR}/camitk-${APPLICATION_NAME}.1 DESTINATION ${CAMITK_APPLICATION_MAN_INSTALL_DIR})
        endif()
    endif()

    # Desktop file
    set(${APPLICATION_NAME_CMAKE}_DESKTOP ${CMAKE_CURRENT_SOURCE_DIR}/resources/camitk-${APPLICATION_NAME}.desktop)
    if (EXISTS ${${APPLICATION_NAME_CMAKE}_DESKTOP})
        message(STATUS "Found desktop file for ${APPLICATION_TARGET_NAME}")
        install(FILES ${${APPLICATION_NAME_CMAKE}_DESKTOP} DESTINATION ${CAMITK_APPLICATION_DESKTOP_INSTALL_DIR})
    endif()

    # application pixmap
    set(${APPLICATION_NAME_CMAKE}_PIXMAP ${CMAKE_CURRENT_SOURCE_DIR}/resources/camitk-${APPLICATION_NAME}.xpm)
    if (EXISTS ${${APPLICATION_NAME_CMAKE}_PIXMAP})
        message(STATUS "Found pixmap for ${APPLICATION_TARGET_NAME}")
        install(FILES ${${APPLICATION_NAME_CMAKE}_PIXMAP} DESTINATION ${CAMITK_APPLICATION_PIXMAP_INSTALL_DIR})
    endif()

endif()

#---------------------------------
# Testing command-line robustness
#---------------------------------
set(TEST_BASENAME ${APPLICATION_TARGET_NAME})
camitk_init_test(${TEST_BASENAME})
# should pass because invoking extensiongenerator without arguments or with help arg shows usage and exit success
camitk_add_test(PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-")
camitk_add_test(EXECUTABLE_ARGS "--help" PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-")
camitk_add_test(EXECUTABLE_ARGS "-h"     PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-")

# test #4
# should pass because invoking extensiongenerator with a faulty arguments results in printing
# an "Argument error" message (and exit failure)
camitk_add_test(EXECUTABLE_ARGS "-badarg" 
                PASS_REGULAR_EXPRESSION "unknown option '-badarg'"
                PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-")

camitk_add_test(EXECUTABLE_ARGS "-f missingdir" 
                PASS_REGULAR_EXPRESSION "Argument error: please provide an output directory."
                PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-")

camitk_add_test(EXECUTABLE_ARGS "-d missingfile" 
                PASS_REGULAR_EXPRESSION "Argument error: please provide an input .camitk JSON file."
                PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-")

camitk_add_test(EXECUTABLE_ARGS "-f badfile -d baddir"
                PASS_REGULAR_EXPRESSION "Error opening .camitk JSON file"
                PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-")

camitk_add_test(EXECUTABLE_ARGS "-f badfile -d ${CMAKE_CURRENT_BINARY_DIR}" 
                PASS_REGULAR_EXPRESSION "Error opening .camitk JSON file" 
                PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-")

camitk_add_test(EXECUTABLE_ARGS "-f ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp -d ${CMAKE_CURRENT_BINARY_DIR}"
                PASS_REGULAR_EXPRESSION "Error reading JSON file"
                PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-")

# Add config test
find_program(BASH_PROGRAM bash)
if(BASH_PROGRAM)
    set(${APPLICATION_TARGET_NAME}_TEST_PYTHON "")
    if(PYTHON_BINDING)
        set(${APPLICATION_TARGET_NAME}_TEST_PYTHON "-python")
    endif()

    # use "ctest -VV -R extensiongenerator-bash-test" to run just this test
    add_test(NAME ${APPLICATION_TARGET_NAME}-bash-test 
             COMMAND ${BASH_PROGRAM} ${CMAKE_CURRENT_SOURCE_DIR}/testing/extensiongenerator-test.sh 
                     -inbuild
                     ${PROJECT_BINARY_DIR} 
                     ${PROJECT_SOURCE_DIR}
                     ${${APPLICATION_TARGET_NAME}_TEST_PYTHON}
             WORKING_DIRECTORY ${CMAKE_BINARY_DIR} # needs to be at the top of the CamiTK module repository
    )
    # add test to this subproject
    set_tests_properties(${APPLICATION_TARGET_NAME}-bash-test PROPERTIES LABELS "${APPLICATION_TARGET_NAME}"
                                                                         RUN_SERIAL TRUE)
    # On Windows, add ${CAMITK_BUILD_PRIVATE_LIB_DIR} and ${CAMITK_BUILD_BIN_DIR} to PATH in order 
    # to find the public and private library dll
    if (MSVC)
        # MSVC requires path to lib for the DLL
        string(REGEX REPLACE "/" "\\\\" PATH_TO_DLL "${CAMITK_BUILD_PRIVATE_LIB_DIR};${CAMITK_BUILD_BIN_DIR}")
        # all ; needs to be escaped as well...
        # see https://developercommunity.visualstudio.com/t/cmake-tests-environment-variables-ignored/210188#T-N931342
        string(REPLACE ";" "\\;" ESCAPED_PATH "$ENV{PATH};${PATH_TO_DLL}") 
        set_tests_properties(${CAMITK_TEST_NAME} PROPERTIES ENVIRONMENT "PATH=${ESCAPED_PATH}")
    endif()

endif()


##############################################################################
#                                                                            #
# Copy cmake modules and macros after build                                  #
# This allows extension generator to run as if CamiTK was installed.         #
# If the current application is in applicationPath, then the cmake modules   #
# and macros can always be found, being a regular CamiTK installation or     #
# during the build, in applicationPath/../${CAMITK_CMAKE_PATH}               #
#                                                                            #
##############################################################################

set(CAMITK_CMAKE_PATH "share/${CAMITK_SHORT_VERSION_STRING}/cmake")
  
# install the generic cmake files
file(GLOB CAMITK_CMAKE_FILES "${CMAKE_SOURCE_DIR}/sdk/cmake/modules/*.cmake")
# copy after build, only if there was a change
foreach(FILE ${CAMITK_CMAKE_FILES})
    get_filename_component(FILE_NAME ${FILE} NAME)
    add_custom_command(
        TARGET ${APPLICATION_TARGET_NAME}
        POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/${CAMITK_CMAKE_PATH}
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FILE} ${CMAKE_BINARY_DIR}/${CAMITK_CMAKE_PATH}/${FILE_NAME}
        COMMENT "Installing modules ${FILE} cmake files"
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        VERBATIM
    )
endforeach()

add_custom_command(
        TARGET ${APPLICATION_TARGET_NAME}
        POST_BUILD
        # make sure it's the new version by deleting previously install directories
        COMMAND ${CMAKE_COMMAND} -E rm -rf ${CMAKE_BINARY_DIR}/${CAMITK_CMAKE_PATH}/macros
        COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/${CAMITK_CMAKE_PATH}/macros
        COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/sdk/cmake/modules/macros ${CMAKE_BINARY_DIR}/${CAMITK_CMAKE_PATH}/macros
        COMMENT "Installing CamiTK macros cmake files"
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        VERBATIM
    )

# add_custom_command(TARGET ${PROJECT_NAME} 
#                    POST_BUILD
#                    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/${CAMITK_CMAKE_PATH}
#                    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CAMITK_CMAKE_FILES} ${CMAKE_BINARY_DIR}/${CAMITK_CMAKE_PATH}
#                    COMMENT 
#                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
#                    VERBATIM
# )

# add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/modules/macros
#                   POST_BUILD
#                   COMMAND ${CMAKE_COMMAND} -E make_directory ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_GROUP}
#                   COMMENT "Creating build-time group include dir ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_GROUP}"
#                  VERBATIM
# )
