#!
#! @ingroup group_sdk_cmake_camitk_test
#!
#! camitk_additional_action_test is a macro to create additional level1 test of CamiTK action
#! to the CTest infrastructure.
#!
#! It should be used when a CEP introduces a new component (with new test files)
#! and an existing action should be run using this new component and test files.
#!
#! Usage:
#! \code
#! camitk_additional_action_test(ACTION_EXTENSIONS action1 action2 ...
#!                               [TEST_FILES  file1 file2 ...]
#!                               [TEST_SUFFIX name]
#! )
#! \endcode
#!
#! \param ACTION_EXTENSIONS      List of the action extension that will be additionnaly tested with the given
#!                               test files. Only the action extension name (not the full library/dll name nor
#!                               the path) should be given. This macro checks the existence of the extension
#!                               library/dll in the following directories (in this order) : build dir;
#!                               user install dir and global install dir. The first one that is found is used for the tests.
#! \param TEST_FILES             Optional. List of files to use for testing. If not set, then all the files in the
#!                               testdata dir are used.
#!                               If provided, only the filenames are required (not the absolute paths) and 
#!                               all the given files should be in the testdata subdir.
#!
#! This will add tests named as follow:
#! "component-[name of the current component extension]-additional-[name of the action extension]-level1-[index]"
#!
#! @sa camitk_extension
macro(camitk_additional_action_test)
    if (NOT PACKAGING_NSIS AND BUILD_TESTING)
        set(options "")
        set(oneValueArgs "")
        set(multiValueArgs ACTION_EXTENSIONS TEST_FILES)
        cmake_parse_arguments(CAMITK_ADDITIONAL_ACTION_TEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

        # COMPONENT_EXTENSION_PLUGIN_FILE
        # determine the extension full file name depending on the plateform
        if (MSVC)
            unset(CURRENT_POSTFIX)
            if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR (CMAKE_CONFIGURATION_TYPES AND "$<CONFIG>" STREQUAL "Debug"))
                set(CURRENT_POSTFIX "${CAMITK_DEBUG_POSTFIX}")
            endif()
            set(COMPONENT_EXTENSION_PLUGIN_FILE "components/${${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME}${CURRENT_POSTFIX}.dll")
        elseif(APPLE)
            set(COMPONENT_EXTENSION_PLUGIN_FILE "components/lib${${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME}.dylib")
        else()
            # Must be Linux
            set(COMPONENT_EXTENSION_PLUGIN_FILE "components/lib${${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME}.so") 
        endif()
        
        # if this is not SDK, then it is required
        if(NOT CAMITK_COMMUNITY_EDITION_BUILD)
            set(ADDITIONAL_COMPONENT_EXTENSION_ARG "-c ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${COMPONENT_EXTENSION_PLUGIN_FILE}")
        endif()
        
        # loop over actions
        #   if (action extension exists in repository) CAMITK_USER_PRIVATE_LIB_DIR CAMITK_PRIVATE_LIB_DIR  CAMITK_BUILD_PRIVATE_LIB_DIR
        #   loop over test files
        #     add test
        #     math(EXPR CAMITK_ADDITIONNAL_TEST_ID "${CAMITK_ADDITIONNAL_TEST_ID} + 1")
        foreach(ACTION_EXTENSION ${CAMITK_ADDITIONAL_ACTION_TEST_ACTION_EXTENSIONS})
            # determine the extension full file name depending on the plateform
            if (MSVC)
                unset(CURRENT_POSTFIX)
                if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR (CMAKE_CONFIGURATION_TYPES AND "$<CONFIG>" STREQUAL "Debug"))
                    set(CURRENT_POSTFIX "${CAMITK_DEBUG_POSTFIX}")
                endif()
                set(EXTENSION_FILE "actions/${ACTION_EXTENSION}${CURRENT_POSTFIX}.dll")
            elseif(APPLE)
                set(EXTENSION_FILE "$actions/lib${ACTION_EXTENSION}.dylib")
            else()
                # Must be Linux
                set(EXTENSION_FILE "actions/lib${ACTION_EXTENSION}.so") 
            endif()
            
            # check if action can be found in (this order) : build dir (CAMITK_BUILD_PRIVATE_LIB_DIR),
            # local user install (CAMITK_USER_PRIVATE_LIB_DIR, and global install (CAMITK_PRIVATE_LIB_DIR)
            set(ACTION_EXTENSION_PLUGIN_FILE ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${EXTENSION_FILE})
            set(ACTION_EXTENSION_TARGET "action-${ACTION_EXTENSION}")
            # The action should already be compiled.
            # if the action does not yet exists, if there is a target of the current project
            # that will build it, then it is ok as well.
            # otherwise, it should be already installed locally or globally
            if ((NOT EXISTS ${ACTION_EXTENSION_PLUGIN_FILE}) AND (NOT TARGET ${ACTION_EXTENSION_TARGET}))
                set(ACTION_EXTENSION_PLUGIN_FILE ${CAMITK_USER_PRIVATE_LIB_DIR}/${EXTENSION_FILE})
                if (NOT EXISTS ${ACTION_EXTENSION_PLUGIN_FILE})
                    set(ACTION_EXTENSION_PLUGIN_FILE ${CAMITK_PRIVATE_LIB_DIR}/${EXTENSION_FILE})
                    if (NOT EXISTS ${ACTION_EXTENSION_PLUGIN_FILE})
                        message(SEND_ERROR "Action extension \"${ACTION_EXTENSION}\" not found: no additional test added")
                        return()
                    endif()
                endif()
            endif()
            
            message(STATUS "Adding additional autotest for action-${ACTION_EXTENSION}")
            if (CAMITK_COMMUNITY_EDITION_BUILD)
                camitk_init_test(application-testactions)
            else()
                camitk_init_test(camitk-testactions)
            endif()
            
            # add a separator to the wiki page information
            camitk_parse_test_add_separator(EXTENSION_TYPE actions EXTENSION_NAME ${ACTION_EXTENSION})

            # Retrieve the files in testdata directory - a test will be applied for each of these files
            # or use only the given files
            if (CAMITK_ADDITIONAL_ACTION_TEST_TEST_FILES)
                # add testdata dir to filename
                set(TESTFILES)
                foreach(COMPONENT_TESTDATA_FILE ${CAMITK_ADDITIONAL_ACTION_TEST_TEST_FILES})
                    list(APPEND TESTFILES ${CMAKE_CURRENT_SOURCE_DIR}/testdata/${COMPONENT_TESTDATA_FILE})
                endforeach()
            else()
                get_subdirectoryfiles( ${CMAKE_CURRENT_SOURCE_DIR}/testdata TESTFILES )
            endif()
                
            foreach(ACTION_TESTDATA_FILE ${TESTFILES})
                # Test procedure: Open a file - load an action extension - Apply an action on the component wrapping the file
                camitk_add_test(EXECUTABLE_ARGS "-i ${ACTION_TESTDATA_FILE} -a ${ACTION_EXTENSION_PLUGIN_FILE} ${ADDITIONAL_COMPONENT_EXTENSION_ARG}" 
                                TEST_SUFFIX "-additional-${ACTION_EXTENSION}-level1-"
                                PROJECT_NAME "component-${EXTENSION_NAME}"
                )
                # add test to the wiki page information 
                camitk_parse_test_add(NAME ${CAMITK_TEST_NAME} LEVEL 1 DESCRIPTION "Open a file, load the action and apply it on the component.")
            endforeach()

        endforeach()
    endif()
endmacro()

