# CMakeLists.txt for GekkoFS Performance Tests
# Standalone performance benchmarks for comparing performance across changes

################################################################################
# Copyright 2018-2025, Barcelona Supercomputing Center (BSC), Spain            #
# Copyright 2015-2025, Johannes Gutenberg Universitaet Mainz, Germany          #
#                                                                              #
# This software is part of GekkoFS.                                            #
#                                                                              #
# GekkoFS is free software: you can redistribute it and/or modify              #
# it under the terms of the GNU General Public License as published by         #
# the Free Software Foundation, either version 3 of the License, or            #
# (at your option) any later version.                                          #
#                                                                              #
# GekkoFS is distributed in the hope that it will be useful,                   #
# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
# GNU General Public License for more details.                                 #
#                                                                              #
# You should have received a copy of the GNU General Public License            #
# along with GekkoFS.  If not, see <https://www.gnu.org/licenses/>.            #
#                                                                              #
# SPDX-License-Identifier: GPL-3.0-or-later                                    #
################################################################################

# Compiler requirements
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Common compile flags (simple list, avoid inheriting CMAKE_CXX_FLAGS as a single string)
set(GKFS_PERF_CXX_FLAGS "-O2" "-Wall")
set(GKFS_PERF_CXX_LINKER_FLAGS "")

# Output directory
set(GKFS_PERF_OUTPUT_DIR "${CMAKE_BINARY_DIR}/perf_tests")
file(MAKE_DIRECTORY ${GKFS_PERF_OUTPUT_DIR})

# ============================================================================
# Performance test executables
# ============================================================================

# Metadata performance test
add_executable(perf_metadata
    perf_metadata.cpp
)
target_compile_options(perf_metadata PRIVATE ${GKFS_PERF_CXX_FLAGS})
target_link_options(perf_metadata PRIVATE ${GKFS_PERF_CXX_LINKER_FLAGS})
target_include_directories(perf_metadata PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}
)
target_link_libraries(perf_metadata
    stdc++fs
)
set_target_properties(perf_metadata PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${GKFS_PERF_OUTPUT_DIR}
)

# Data performance test
add_executable(perf_data
    perf_data.cpp
)
target_compile_options(perf_data PRIVATE ${GKFS_PERF_CXX_FLAGS})
target_link_options(perf_data PRIVATE ${GKFS_PERF_CXX_LINKER_FLAGS})
target_include_directories(perf_data PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}
)
set_target_properties(perf_data PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${GKFS_PERF_OUTPUT_DIR}
)

# Delete performance test
add_executable(perf_delete
    perf_delete.cpp
)
target_compile_options(perf_delete PRIVATE ${GKFS_PERF_CXX_FLAGS})
target_link_options(perf_delete PRIVATE ${GKFS_PERF_CXX_LINKER_FLAGS})
target_include_directories(perf_delete PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}
)
set_target_properties(perf_delete PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${GKFS_PERF_OUTPUT_DIR}
)

# Find/search performance test
add_executable(perf_find
    perf_find.cpp
)
target_compile_options(perf_find PRIVATE ${GKFS_PERF_CXX_FLAGS})
target_link_options(perf_find PRIVATE ${GKFS_PERF_CXX_LINKER_FLAGS})
target_include_directories(perf_find PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}
)
set_target_properties(perf_find PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${GKFS_PERF_OUTPUT_DIR}
)

# Directory performance test
add_executable(perf_directory
    perf_directory.cpp
)
target_compile_options(perf_directory PRIVATE ${GKFS_PERF_CXX_FLAGS})
target_link_options(perf_directory PRIVATE ${GKFS_PERF_CXX_LINKER_FLAGS})
target_include_directories(perf_directory PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}
)
set_target_properties(perf_directory PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${GKFS_PERF_OUTPUT_DIR}
)

# ============================================================================
# Custom targets for running benchmarks
# ============================================================================

# Run all benchmarks (requires mounted filesystem)
add_custom_target(run-all-perf-tests
    COMMAND ${CMAKE_COMMAND} -E echo "Please mount your filesystem first, then run:"
    COMMAND ${CMAKE_COMMAND} -E echo "  ./perf_metadata --mountdir /mnt/gekkofs"
    COMMAND ${CMAKE_COMMAND} -E echo "  ./perf_data --mountdir /mnt/gekkofs"
    COMMAND ${CMAKE_COMMAND} -E echo "  ./perf_delete --mountdir /mnt/gekkofs"
    COMMAND ${CMAKE_COMMAND} -E echo "  ./perf_find --mountdir /mnt/gekkofs"
    COMMAND ${CMAKE_COMMAND} -E echo "  ./perf_directory --mountdir /mnt/gekkofs"
    DEPENDS perf_metadata perf_data perf_delete perf_find perf_directory
    WORKING_DIRECTORY ${GKFS_PERF_OUTPUT_DIR}
    COMMENT "Build complete. Run benchmarks manually on a mounted filesystem."
)

# Run benchmarks with runner script
add_custom_target(run-all-perf-with-script
    COMMAND ${CMAKE_COMMAND} -E echo "Running benchmarks with runner script..."
    COMMAND ${CMAKE_COMMAND} -E chdir ${GKFS_PERF_OUTPUT_DIR} ./run_benchmarks.sh
    DEPENDS perf_metadata perf_data perf_delete perf_find perf_directory
    WORKING_DIRECTORY ${GKFS_PERF_OUTPUT_DIR}
    COMMENT "Running all benchmarks with default settings."
)

# Install targets
install(TARGETS perf_metadata perf_data perf_delete perf_find perf_directory
        RUNTIME DESTINATION bin)
install(FILES run_benchmarks.sh run_all_benchmarks.py
        DESTINATION bin
        PERMISSIONS
            OWNER_READ OWNER_WRITE OWNER_EXECUTE
            GROUP_READ GROUP_EXECUTE
            WORLD_READ WORLD_EXECUTE)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
        DESTINATION share/gekkofs/perf_tests
        FILES_MATCHING
                 PATTERN "*.hpp"
                 PATTERN "README.md")
install(FILES run_benchmarks.sh run_all_benchmarks.py
        DESTINATION share/gekkofs/perf_tests
        PERMISSIONS
            OWNER_READ OWNER_WRITE OWNER_EXECUTE
            GROUP_READ GROUP_EXECUTE
            WORLD_READ WORLD_EXECUTE)
