# -----------------------------------------------------------------------------
# MCDS Trace Viewer
# -----------------------------------------------------------------------------
# read the current version from the header file
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/mcds_trace_viewer_version.h" ver)

string(REGEX MATCH "VERSION_MAJOR[ \t]+([0-9]*)" _ ${ver})
set(ver_major ${CMAKE_MATCH_1})

string(REGEX MATCH "VERSION_MINOR[ \t]+([0-9]*)" _ ${ver})
set(ver_minor ${CMAKE_MATCH_1})

string(REGEX MATCH "VERSION_PATCH[ \t]+([0-9]*)" _ ${ver})
set(ver_patch ${CMAKE_MATCH_1})

message("MCDS Trace Viewer version: ${ver_major}.${ver_minor}.${ver_patch}")

# Version set by the mcds_trace_viewer_version.h
set(MCDS_VERSION_MAJOR ${ver_major})
set(MCDS_VERSION_MINOR ${ver_minor})
set(MCDS_VERSION_PATCH ${ver_patch})
set(MCDS_VERSION_TWEAK 0)

set(MCDS_APP_NAME "mcds_trace_viewer")
set(MCDS_APP_DESC "MCDS Trace Viewer")
configure_file(
    ${CMAKE_SOURCE_DIR}/cmake/templates/mcds_app.rc.in
    ${CMAKE_CURRENT_BINARY_DIR}/mcds_trace_viewer.rc
)
# -----------------------------------------------------------------------------
# Relevant source files and their virtual folders for IDE (source groups)
# -----------------------------------------------------------------------------
set(NO_GROUP_SRCS
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_trace_table_msg_native.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_trace_table_msg_native.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_trace_table.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_trace_viewer_main.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_trace_viewer_version.h"
    "${CMAKE_CURRENT_BINARY_DIR}/mcds_trace_viewer.rc"
)

set(MCDS_TRACE_VIEWER_FL_SRCS
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_tools.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_tools.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_tools_win_mcds.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_tools_win_mcds.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_tools_win_mcds_general.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_tools_win_mcds_opoint.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_tools_win_mcds_otgb.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/fl_mcds_tools_win_mcds_trace_info.cpp"
)

set(MCDS_TRACE_VIEWER_UTIL_SRCS
    "${CMAKE_SOURCE_DIR}/src/mcds_tools/mcds_rich_recorder.cpp"
    "${CMAKE_SOURCE_DIR}/src/mcds_tools/mcds_rich_recorder.h"
    "${CMAKE_SOURCE_DIR}/src/mcds_tools/mcds_mtsc.cpp"
    "${CMAKE_SOURCE_DIR}/src/mcds_tools/mcds_mtsc.h"
    "${CMAKE_SOURCE_DIR}/src/mcds/mcds_decoder_fast.cpp"
    "${CMAKE_SOURCE_DIR}/src/mcds/mcds_decoder_fast.h"
    "${CMAKE_SOURCE_DIR}/src/mcds_lib/mcds_frequency_measurement.cpp"
    "${CMAKE_SOURCE_DIR}/src/mcds_lib/mcds_frequency_measurement.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_file_handler.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_file_handler.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_file_io.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_file_io.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_file_io_basic.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_file_io_basic.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_file_io_mcr.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_file_io_mcr.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/mcds_lib_decoder_utils.h"
)

# TAS GUI sources — wrapped in an OBJECT library so that viewer
# target_sources contains only files under apps/mcds_trace_viewer/.
add_library(tas_client_gui OBJECT
    "${CMAKE_SOURCE_DIR}/external/tas_client_apps/src/common/tas_client_gui.h"
    "${CMAKE_SOURCE_DIR}/external/tas_client_apps/src/common/tas_client_gui_select_device.cpp"
    "${CMAKE_SOURCE_DIR}/external/tas_client_apps/src/common/tas_client_gui_con_info.cpp"
    "${CMAKE_SOURCE_DIR}/external/tas_client_apps/src/common/tas_client_gui_unlock_device.cpp"
    "${CMAKE_SOURCE_DIR}/external/tas_client_apps/src/common/tas_client_gui_acc_hw_ctrl.cpp"
)
target_include_directories(tas_client_gui
    PUBLIC
        "${CMAKE_SOURCE_DIR}/external/tas_client_apps/src/common/"
)
target_link_libraries(tas_client_gui
    PRIVATE
        fltk::fltk
        tas_client_api::tas_client
)

target_sources(mcds_trace_viewer
    PRIVATE
        ${NO_GROUP_SRCS}
        ${MCDS_TRACE_VIEWER_FL_SRCS}
        ${MCDS_TRACE_VIEWER_UTIL_SRCS}
)

# In shared builds the generated reg_name sources (CRegName, RegName global)
# are internal to the configurator/decoder DLLs and not exported.  Compile
# them directly into the viewer so the symbols are available.
if(BUILD_SHARED_LIBS)
    target_sources(mcds_trace_viewer PRIVATE
        "${CMAKE_SOURCE_DIR}/src/generated/reg_name.cpp"
        "${CMAKE_SOURCE_DIR}/src/generated/reg_name.h"
        "${CMAKE_SOURCE_DIR}/src/generated/reg_name_tc2.cpp"
        "${CMAKE_SOURCE_DIR}/src/generated/reg_name_tc3.cpp"
        "${CMAKE_SOURCE_DIR}/src/generated/reg_name_tc4.cpp"
        "${CMAKE_SOURCE_DIR}/src/generated/reg_name_rc1.cpp"
    )
endif()


# -----------------------------------------------------------------------------
# Find relevant dependencies
# -----------------------------------------------------------------------------


# -----------------------------------------------------------------------------
# includes, and libraries
# -----------------------------------------------------------------------------
target_include_directories(mcds_trace_viewer
    PRIVATE
        "${CMAKE_CURRENT_SOURCE_DIR}"
        "${CMAKE_SOURCE_DIR}/include/mcds_libs"
        "${CMAKE_SOURCE_DIR}/src"
        "${CMAKE_SOURCE_DIR}/src/mcds_lib"
        "${CMAKE_SOURCE_DIR}/src/mcds_tools"
        ${fltk_INCLUDE_DIRS}
        ${tas_client_api_INCLUDE_DIRS}
        ${elf_disasm_INCLUDE_DIRS}
        ${capstone_INCLUDE_DIRS}
        "${CMAKE_SOURCE_DIR}/data/icons"
        "${CMAKE_BINARY_DIR}"
)

target_link_libraries(mcds_trace_viewer
    PRIVATE
    tas_client_gui
    mcds_configurator
    mcds_decoder
    mcds_recorder
    elf_disasm::elf_disasm_tc
    capstone::capstone
    tas_client_api::tas_client
    fltk::fltk
    nlohmann_json::nlohmann_json
    nlohmann_json_schema_validator
    spdlog::spdlog
)

# Setup RPTAHs
if(APPLE)
    set(INSTALL_RPATH "$loader_path/../lib")
elseif(UNIX)
    set(INSTALL_RPATH "$ORIGIN/../lib")
else()
    set(INSTALL_RPATH "")
endif()

# Set RPATH for the executable during build and install
set_target_properties(mcds_trace_viewer
    PROPERTIES
        BUILD_RPATH "$<TARGET_FILE_DIR:mcds_recorder>"
        INSTALL_RPATH "${INSTALL_RPATH}"
        INSTALL_RPATH_USE_LINK_PATH FALSE
)

# Ensure install() does not strip RPATH
set(CMAKE_SKIP_INSTALL_RPATH FALSE)

# Needed to for Visual Studio debug environment to locate the build dlls
# Note: not required for this project since all libraries and executable
# are defined in the top level CMakeLists file under mcds dir
set_target_properties(mcds_trace_viewer
    PROPERTIES
        # Paths are the same for decoder and configurator dll
        VS_DEBUGGER_ENVIRONMENT "PATH=$<TARGET_FILE_DIR:mcds_recorder>;%PATH%"
)

# -----------------------------------------------------------------------------
# Compile definitions
# -----------------------------------------------------------------------------
if (MSVC)
    target_compile_definitions(mcds_trace_viewer PRIVATE
        "$<$<CONFIG:Debug>:"
            "_DEBUG"
        ">"
        "$<$<CONFIG:Release>:"
            "NDEBUG"
        ">"
        "_CRT_SECURE_NO_WARNINGS"
        "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES;"
        "_WIN32"
        "TSIM64"
        "WIN32_LEAN_AND_MEAN"
        "LITTLE_ENDIAN_HOST"
    )
elseif (UNIX)
    target_compile_definitions(mcds_trace_viewer PRIVATE
        "UNIX"
    )
endif()

# -----------------------------------------------------------------------------
# Compile and link options
# -----------------------------------------------------------------------------
if (MSVC)
    target_compile_options(mcds_trace_viewer PRIVATE
        /W3
        /MP
    )

    target_link_options(mcds_trace_viewer PRIVATE
        /SUBSYSTEM:WINDOWS
    )

    if(BUILD_SHARED_LIBS)
        target_link_options(mcds_trace_viewer PRIVATE /INCREMENTAL)
    else()
        # Static builds: viewer-local file I/O copies overlap with identical
        # definitions inside the configurator/decoder static libs.
        # Harmless — same source, refactored to use C API.
        # Long-term fix: factor shared sources into mcds_core.
        target_link_options(mcds_trace_viewer PRIVATE /FORCE:MULTIPLE)
    endif()
elseif (UNIX)
    target_compile_options(mcds_trace_viewer PRIVATE
        -Wall;
    )
    target_link_libraries(mcds_trace_viewer PRIVATE pthread dl)
endif()

# -----------------------------------------------------------------------------
# Install
# -----------------------------------------------------------------------------
install(TARGETS mcds_trace_viewer DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT applications)
