# As this script is run in a new cmake instance, it does not have access to
# the existing cache variables. Pass them in via the configure_file command.
set(CMAKE_BINARY_DIR @CMAKE_BINARY_DIR@)
set(CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@)
set(USE_INTERNAL_CODEC2 @USE_INTERNAL_CODEC2@)
set(UNIX @UNIX@)
set(WIN32 @WIN32@)
set(CMAKE_CROSSCOMPILING @CMAKE_CROSSCOMPILING@)
set(CMAKE_FIND_LIBRARY_SUFFIXES @CMAKE_FIND_LIBRARY_SUFFIXES@)
set(CMAKE_FIND_LIBRARY_PREFIXES @CMAKE_FIND_LIBRARY_PREFIXES@)
set(CMAKE_SYSTEM_LIBRARY_PATH @CMAKE_SYSTEM_LIBRARY_PATH@)
set(CMAKE_FIND_ROOT_PATH @CMAKE_FIND_ROOT_PATH@)
if(USE_INTERNAL_CODEC2)
    set(CODEC2_BUILD_DIR ${CMAKE_BINARY_DIR}/codec2_build)
else()
    set(CODEC2_BUILD_DIR @CODEC2_BUILD_DIR@)
endif()


set(FREEDV_USING_LLVM_MINGW @FREEDV_USING_LLVM_MINGW@)
set(FREEDV_PACKAGE_SEARCH_PATHS @FREEDV_PACKAGE_SEARCH_PATHS@)
list(APPEND FREEDV_PACKAGE_SEARCH_PATHS ${CMAKE_BINARY_DIR}/external/dist/bin)

set(CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM windows+pe)
set(CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL objdump)
set(CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND ${CMAKE_OBJDUMP})

#message("dependency platform: ${CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM}")
#message("dependency tool: ${CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL}")
#message("dependency command: ${CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND}")

set(FREEDV_EXE ${CMAKE_BINARY_DIR}/src/freedv.exe)

# Implement our own GetDependencies because the CMake one
# isn't working for some reason when using LLVM.
macro(freedv_get_dependencies OUTPUT_VAR FILENAME)
    execute_process(
        COMMAND ${CMAKE_OBJDUMP} -p ${FILENAME}
        COMMAND grep "DLL Name:" 
        COMMAND awk "{ printf \"%s;\", \$3; }"
        COMMAND sed "s/;$//"
        OUTPUT_VARIABLE ${OUTPUT_VAR})
endmacro()

# Code signing function
set(SIGN_WINDOWS_BINARIES @SIGN_WINDOWS_BINARIES@)
function(freedv_sign_dependency FILENAME OUT)
    if(SIGN_WINDOWS_BINARIES)
        execute_process(
            COMMAND @OSSLSIGNCODE_BIN@ sign -pkcs11engine @PKCS11_ENGINE@ -pkcs11module @PKCS11_MODULE@ -pkcs11cert "@PKCS11_CERTIFICATE@" -key "@PKCS11_KEY@" -h @SIGN_HASH@ -comm -ts @TIMESTAMP_SERVER@ -ac @INTERMEDIATE_CERT_FILE@ -n "FreeDV - @PROJECT_DESCRIPTION@" -i "https://freedv.org/" -in "${FILENAME}" -out "${OUT}"
        )
    else(SIGN_WINDOWS_BINARIES)
        execute_process(
            COMMAND cp "${FILENAME}" "${OUT}"
        )
    endif(SIGN_WINDOWS_BINARIES)
endfunction()

freedv_get_dependencies(_deps ${FREEDV_EXE})

message("Found Win32 dependencies: ${_deps}")

# Filter libraries known to be provided by Windows
set( _windlls
    ADVAPI32.dll
    GDI32.dll
    KERNEL32.dll
    SHELL32.dll
    USER32.dll
    WS2_32.dll
    WSOCK32.dll
    WSOCK32.DLL
    WINMM.dll
    WINMM.DLL
    ole32.dll
    COMCTL32.dll
    COMCTL32.DLL
    OLEAUT32.dll
    RPCRT4.dll
    comdlg32.dll
    COMDLG32.DLL
    SETUPAPI.dll
    WINSPOOL.DRV
    VERSION.dll
    SHLWAPI.dll
    UxTheme.dll
    OLEACC.dll
    msvcrt.dll
    bcrypt.dll
    IPHLPAPI.DLL
    AVRT.dll
    gdiplus.dll
    MSIMG32.dll

    # The below are additional DLLs required when compiled
    # using the LLVM version of MinGW.

    api-ms-win-crt-locale-l1-1-0.dll
    api-ms-win-crt-filesystem-l1-1-0.dll
    api-ms-win-crt-environment-l1-1-0.dll
    api-ms-win-crt-utility-l1-1-0.dll
    api-ms-win-crt-time-l1-1-0.dll
    api-ms-win-crt-string-l1-1-0.dll
    api-ms-win-crt-stdio-l1-1-0.dll
    api-ms-win-crt-runtime-l1-1-0.dll
    api-ms-win-crt-private-l1-1-0.dll
    api-ms-win-crt-math-l1-1-0.dll
    api-ms-win-crt-heap-l1-1-0.dll
    api-ms-win-crt-convert-l1-1-0.dll
    api-ms-win-crt-multibyte-l1-1-0.dll

    # Filter Python DLLs as they're already included via install()
    python312.dll

    # Additional DLLs needed by Address Sanitizer
    api-ms-win-core-synch-l1-2-0.dll
)
list(REMOVE_ITEM _deps ${_windlls})

execute_process(
    COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/bin
)

# Handle internal libraries separately.
if(CODEC2_BUILD_DIR)
    list(REMOVE_ITEM _deps libcodec2.dll)
    find_library(CODEC2 codec2 NO_DEFAULT_PATH PATHS ${CODEC2_BUILD_DIR}/src REQUIRED)
    string(REPLACE ".a" "" CODEC2_FINAL ${CODEC2})

    message("Found: libcodec2.dll")
    #file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
    #    TYPE EXECUTABLE FILES ${CODEC2_FINAL})

    freedv_sign_dependency(${CODEC2_FINAL} ${CMAKE_INSTALL_PREFIX}/bin/libcodec2.dll)
endif()

if(FREEDV_USING_LLVM_MINGW)
    # Use the bin/ folder for the platform as an additional
    # search path for find_library.
    find_program(OBJDUMP_PATH ${CMAKE_OBJDUMP})
    string(REPLACE "-objdump" "" LLVM_ARCH_TRIPLE ${CMAKE_OBJDUMP})

    string(REPLACE ${CMAKE_OBJDUMP} "" OBJDUMP_PATH ${OBJDUMP_PATH})
    string(APPEND LLVM_ADDITIONAL_LIB_PATH ${OBJDUMP_PATH} "../" ${LLVM_ARCH_TRIPLE} "/bin")
    cmake_path(NORMAL_PATH LLVM_ADDITIONAL_LIB_PATH)
    message("Using ${LLVM_ADDITIONAL_LIB_PATH} for dependency searches.")
    list(APPEND FREEDV_PACKAGE_SEARCH_PATHS ${LLVM_ADDITIONAL_LIB_PATH})
endif(FREEDV_USING_LLVM_MINGW)

message("dependency search paths: ${FREEDV_PACKAGE_SEARCH_PATHS}")

# Process remaining dependencies.
list(LENGTH _deps _dep_len)
message("There are ${_dep_len} dependencies to scan.")
while(_deps)
    foreach(_runtime ${_deps})
        message("Looking for ${_runtime}")
        #if(FREEDV_USING_LLVM_MINGW)
            find_file(RUNTIME_${_runtime} NAMES ${_runtime} PATHS ${FREEDV_PACKAGE_SEARCH_PATHS} REQUIRED)
        #else(FREEDV_USING_LLVM_MINGW)
        #    find_library(RUNTIME_${_runtime} NAMES ${_runtime} PATHS ${FREEDV_PACKAGE_SEARCH_PATHS} REQUIRED)
        #endif(FREEDV_USING_LLVM_MINGW)
        if(RUNTIME_${_runtime})
            message("Found: ${RUNTIME_${_runtime}}")
            #file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
            #    TYPE EXECUTABLE FILES "${RUNTIME_${_runtime}}")

            freedv_sign_dependency(${RUNTIME_${_runtime}} ${CMAKE_INSTALL_PREFIX}/bin/${_runtime})

            freedv_get_dependencies(_newdep "${CMAKE_INSTALL_PREFIX}/bin/${_runtime}")
            list(APPEND _newdeps ${_newdep})
            list(APPEND _good_deps ${_runtime})
        else()
            message("Warning: ${_runtime} not found.")
            list(APPEND _bad_deps ${_runtime})
        endif()
    endforeach()
    # Try to figure out if there are new dependencies or not.
    list(REMOVE_DUPLICATES _newdeps)
    list(REMOVE_ITEM _newdeps ${_deps};${_good_deps};${_bad_deps};${_windlls})
    set(_deps ${_newdeps})
endwhile()
