set(TEST_DEPENDENCY_LIB "-lstdc++fs")
set(DFTRACER_DATA_DIR ${CMAKE_CURRENT_BINARY_DIR}/data)
include_directories(${DFTRACER_PROJECT_DIR}/include)
if(DEFINED ENV{DFTRACER_DATA_DIR})
    set(DFTRACER_DATA_DIR $ENV{DFTRACER_DATA_DIR})
endif()
message(STATUS "[DFTRACER] using data dir as ${DFTRACER_DATA_DIR}")
if(NOT DEFINED ENV{DARSHAN_PRELOAD_LIB})
    message(FATAL_ERROR "-- [DFTRACER] DARSHAN_PRELOAD_LIB in env should be set for ${PROJECT_NAME} paper test build")
else()
    message(STATUS "[DFTRACER] found Darshan at $ENV{DARSHAN_PRELOAD_LIB}")
endif()
if(NOT DEFINED ENV{DFTRACER_TEST_MACHINE})
    message(FATAL_ERROR "-- [DFTRACER] DFTRACER_TEST_MACHINE in env should be set for ${PROJECT_NAME} paper test build")
else()
    message(STATUS "[DFTRACER] found setting machine to $ENV{DFTRACER_TEST_MACHINE}")
endif()


find_package(MPI REQUIRED COMPONENTS CXX)
if (${MPI_FOUND})
    message(STATUS "[DFTRACER] found MPI at ${MPI_CXX_INCLUDE_DIRS}")
    include_directories(${MPI_CXX_INCLUDE_DIRS})
    set(TEST_DEPENDENCY_LIB ${TEST_DEPENDENCY_LIB} ${MPI_CXX_LIBRARIES})
else ()
    message(FATAL_ERROR "-- [DFTRACER] MPI is needed for ${PROJECT_NAME} paper test build")
endif ()
find_package(cpp-logger 1.0.0 REQUIRED)
if (${cpp-logger_FOUND})
    include_directories(${CPP_LOGGER_INCLUDE_DIRS})
    set(TEST_DEPENDENCY_LIB ${TEST_DEPENDENCY_LIB} ${CPP_LOGGER_LIBRARIES})
    message(STATUS "[DFTRACER] found cpp-logger at ${CPP_LOGGER_INCLUDE_DIRS}")
else ()
    message(FATAL_ERROR "-- [DFTRACER] cpp-logger is needed for ${PROJECT_NAME} build")
endif ()

function(compile_test example)
    add_executable(${example} ${example}.cpp ${TEST_SRC})
    target_link_libraries(${example} ${TEST_DEPENDENCY_LIB})
    target_include_directories(${example}
            PRIVATE
            # where the library itself will look for its internal headers
            ${DFTRACER_PROJECT_DIR}/src
            PUBLIC
            # where top-level project will look for the library's public headers
            $<BUILD_INTERFACE:${DFTRACER_PROJECT_DIR}/include>
            # where external projects will look for the library's public headers
            $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
            )
endfunction()

function(add_base_test machine PPN NODES example example_name)
    if (${machine} STREQUAL "local" AND "${PPN}" STREQUAL "1")
        set(mpi_exec)
    elseif (${machine} STREQUAL "local")
        set(mpi_exec mpirun -n ${PPN})
    elseif (${machine} STREQUAL "lassen")
        set(mpi_exec jsrun -r 1 -a ${PPN} -c ${PPN} -d packed)
    elseif (${machine} STREQUAL "corona")
        set(mpi_exec srun -N ${NODES} --ntasks-per-node=${PPN})
    endif ()
    set(test_name test_paper_${example_name}_${machine}_${NODES}_${PPN})
    list(SUBLIST ARGV 4 10 TEST_ARGS)
    #message(INFO ${test_name})
    add_test(${test_name} ${mpi_exec} ${CMAKE_BINARY_DIR}/bin/${example} ${TEST_ARGS})
endfunction()

function(add_df_test machine PPN NODES example example_name)
    set(example_name "df_${example_name}")
    list(SUBLIST ARGV 5 10 TEST_ARGS)
    add_base_test(${machine} ${PPN} ${NODES} ${example} ${example_name} ${TEST_ARGS})
    set(test_name test_paper_${example_name}_${machine}_${NODES}_${PPN})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT LD_PRELOAD=${CMAKE_BINARY_DIR}/${DFTRACER_LIBDIR}/libdftracer_preload.so)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_DATA_DIR=${DFTRACER_DATA_DIR})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_LOG_FILE=${CMAKE_CURRENT_BINARY_DIR}/${test_name})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_INIT=PRELOAD)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_ENABLE=1)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_LOG_LEVEL=INFO)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_TRACE_COMPRESSION=0)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_INC_METADATA=1)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_TRACE_ALL_FILES=1)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_TRACE_TIDS=0)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_BIND_SIGNALS=0)
endfunction()

function(add_darshan_test machine PPN NODES example example_name)
    set(example_name "darshan_${example_name}")
    list(SUBLIST ARGV 5 10 TEST_ARGS)
    add_base_test(${machine} ${PPN} ${NODES} ${example} ${example_name} ${TEST_ARGS})
    set(test_name test_paper_${example_name}_${machine}_${NODES}_${PPN})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT LD_PRELOAD=$ENV{DARSHAN_PRELOAD_LIB})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DARSHAN_LOG_DIR=${CMAKE_CURRENT_BINARY_DIR})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DXT_ENABLE_IO_TRACE=1)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DARSHAN_ENABLE_NONMPI=1)
endfunction()

file(MAKE_DIRECTORY ${DFTRACER_DATA_DIR})

compile_test(overhead)
set(nodes 1 2 4 8 16 32)
set(OPS 100)
set(TS 131072)
foreach(node ${nodes})
    add_base_test($ENV{DFTRACER_TEST_MACHINE} 40 ${node} overhead overhead ${DFTRACER_DATA_DIR} ${OPS} ${TS})
    add_df_test($ENV{DFTRACER_TEST_MACHINE} 40 ${node} overhead overhead ${DFTRACER_DATA_DIR} ${OPS} ${TS})
    add_darshan_test($ENV{DFTRACER_TEST_MACHINE} 40 ${node} overhead overhead ${DFTRACER_DATA_DIR} ${OPS} ${TS})
endforeach()
add_df_test(local 1 1 overhead overheadd ${DFTRACER_DATA_DIR} 10240 4096)



function(add_py_base_test machine PPN NODES example example_name)
    if (${machine} STREQUAL "local" AND "${PPN}" STREQUAL "1")
        set(mpi_exec)
    elseif (${machine} STREQUAL "local")
        set(mpi_exec mpirun -n ${PPN})
    elseif (${machine} STREQUAL "lassen")
        set(mpi_exec jsrun -r 1 -a ${PPN} -c ${PPN} -d packed)
    elseif (${machine} STREQUAL "corona")
        set(mpi_exec srun -N ${NODES} --ntasks-per-node=${PPN})
    endif ()
    set(test_name test_paper_${example_name}_${machine}_${NODES}_${PPN})
    list(SUBLIST ARGV 4 10 TEST_ARGS)
    #message(INFO ${test_name})
    add_test(${test_name} ${mpi_exec} python ${CMAKE_CURRENT_SOURCE_DIR}/${example} ${TEST_ARGS})
endfunction()

function(add_py_df_test machine PPN NODES example example_name)
    set(example_name "df_${example_name}")
    list(SUBLIST ARGV 5 10 TEST_ARGS)
    add_py_base_test(${machine} ${PPN} ${NODES} ${example} ${example_name} ${TEST_ARGS})
    set(test_name test_paper_${example_name}_${machine}_${NODES}_${PPN})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_DATA_DIR=${DFTRACER_DATA_DIR})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_LOG_FILE=${CMAKE_CURRENT_BINARY_DIR}/${test_name})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_INIT=FUNCTION)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_ENABLE=1)
    #set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_LOG_LEVEL=INFO)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_TRACE_COMPRESSION=1)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_INC_METADATA=0)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_TRACE_TIDS=0)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_BIND_SIGNALS=0)
endfunction()

function(add_py_darshan_test machine PPN NODES example example_name)
    set(example_name "darshan_${example_name}")
    list(SUBLIST ARGV 5 10 TEST_ARGS)
    add_py_base_test(${machine} ${PPN} ${NODES} ${example} ${example_name} ${TEST_ARGS})
    set(test_name test_paper_${example_name}_${machine}_${NODES}_${PPN})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT LD_PRELOAD=$ENV{DARSHAN_PRELOAD_LIB})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DARSHAN_LOG_DIR=${CMAKE_CURRENT_BINARY_DIR})
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DXT_ENABLE_IO_TRACE=1)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_ENABLE=0)
    set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DARSHAN_ENABLE_NONMPI=1)
endfunction()


set(TS 64072)
foreach(node ${nodes})
    add_py_base_test($ENV{DFTRACER_TEST_MACHINE} 40 ${node} overhead.py overhead_py ${DFTRACER_DATA_DIR} ${OPS} ${TS})
    add_py_df_test($ENV{DFTRACER_TEST_MACHINE} 40 ${node} overhead.py overhead_py ${DFTRACER_DATA_DIR} ${OPS} ${TS})
    add_py_darshan_test($ENV{DFTRACER_TEST_MACHINE} 40 ${node} overhead.py overhead_py ${DFTRACER_DATA_DIR} ${OPS} ${TS})
endforeach()
add_py_df_test(local 1 1 overhead overhead ${DFTRACER_DATA_DIR} 10240 4096)
