# Generate the config.h file
# ===========================
# This creates config/gridcoin-config.h in the build directory
# (e.g., build/config/gridcoin-config.h) with all the
# correct HAVE_... definitions from the checks above.
configure_file(
    config/gridcoin-config.h.cmake.in
    config/gridcoin-config.h
)
configure_file(
    obj/build.h.in
    obj/build.h
)

add_compile_definitions(
    BOOST_SPIRIT_THREADSAFE
    __STDC_FORMAT_MACROS
)

if(WIN32)
    # _WIN32_WINNT is already defined by the toolchain/CMake.
    # We remove it here to avoid "redefined" warnings.
    add_compile_definitions(_MT _WINDOWS)
    add_compile_definitions(WIN32 BOOST_THREAD_USE_LIB UNICODE)
elseif(UNIX AND NOT APPLE)
    add_compile_definitions(_FILE_OFFSET_BITS=64)
endif()

# These two files MUST be removed during a cmake build to ensure that an unclean autotools
# in-source build does not pollute the cmake build process.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/config/gridcoin-config.h")
    message(STATUS "Detected stale Autotools configuration file. Removing: ${CMAKE_CURRENT_SOURCE_DIR}/config/gridcoin-config.h")
    file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/config/gridcoin-config.h")
endif()

if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/obj/build.h")
    message(STATUS "Detected stale Autotools configuration file. Removing: ${CMAKE_CURRENT_SOURCE_DIR}/obj/build.h")
    file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/obj/build.h")
endif()

# Dependencies
# ============

if(SYSTEM_BDB)
    set(LIBBDB_CXX BerkeleyDB::CXX)
else()
    add_subdirectory(bdb53)
    set(LIBBDB_CXX libdb_cxx)
endif()

if(SYSTEM_LEVELDB)
    set(LIBLEVELDB leveldb::leveldb)
else()
    set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)

    set(LEVELDB_BUILD_TESTS OFF)
    set(LEVELDB_BUILD_BENCHMARKS OFF)
    set(LEVELDB_INSTALL OFF)

    set(HAVE_CRC32C OFF)
    set(HAVE_SNAPPY OFF)
    set(HAVE_TCMALLOC OFF)
    set(HAVE_CLANG_THREAD_SAFETY OFF)

    set(BUILD_SHARED_LIBS_ORIG ${BUILD_SHARED_LIBS})
    set(BUILD_SHARED_LIBS OFF)

    add_subdirectory(leveldb)
    set(LIBLEVELDB leveldb)

    set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_ORIG})
endif()

if(SYSTEM_SECP256K1)
    set(LIBSECP256K1 PkgConfig::SECP256K1)
else()
    set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)

    set(SECP256K1_DISABLE_SHARED ON CACHE BOOL "" FORCE)
    set(SECP256K1_ENABLE_MODULE_ECDH OFF)
    set(SECP256K1_ENABLE_MODULE_RECOVERY ON)
    set(SECP256K1_ENABLE_MODULE_EXTRAKEYS OFF)
    set(SECP256K1_ENABLE_MODULE_SCHNORRSIG OFF)
    set(SECP256K1_ENABLE_MODULE_MUSIG OFF)
    set(SECP256K1_VALGRIND OFF)

    set(SECP256K1_BUILD_BENCHMARK OFF)
    set(SECP256K1_BUILD_TESTS OFF)
    set(SECP256K1_BUILD_EXHAUSTIVE_TESTS OFF)
    set(SECP256K1_BUILD_CTIME_TESTS OFF)

    if(USE_ASM)
        set(SECP256K1_ASM "AUTO")
    else()
        set(SECP256K1_ASM "OFF")
    endif()

    add_subdirectory(secp256k1 EXCLUDE_FROM_ALL)
    set(LIBSECP256K1 secp256k1)
endif()

if(SYSTEM_UNIVALUE)
    set(LIBUNIVALUE PkgConfig::UNIVALUE)
else()
    add_subdirectory(univalue)
    set(LIBUNIVALUE univalue)
endif()


# libgridcoin_crypto
# ==================

add_subdirectory(crypto)


# libgridcoin_util
# ================

add_library(gridcoin_util STATIC
    addrdb.cpp
    addrman.cpp
    alert.cpp
    arith_uint256.cpp
    banman.cpp
    base58.cpp
    chainparams.cpp
    chainparamsbase.cpp
    checkpoints.cpp
    clientversion.cpp
    consensus/merkle.cpp
    consensus/tx_verify.cpp
    crypter.cpp
    dbwrapper.cpp
    fs.cpp
    htlc.cpp
    gridcoin/backup.cpp
    gridcoin/beacon.cpp
    gridcoin/boinc.cpp
    gridcoin/crypto/rsaverify.cpp
    gridcoin/claim.cpp
    gridcoin/contract/contract.cpp
    gridcoin/contract/message.cpp
    gridcoin/contract/registry.cpp
    gridcoin/cpid.cpp
    gridcoin/gridcoin.cpp
    gridcoin/mrc.cpp
    gridcoin/project.cpp
    gridcoin/protocol.cpp
    gridcoin/quorum.cpp
    gridcoin/researcher.cpp
    gridcoin/scraper/http.cpp
    gridcoin/scraper/scraper.cpp
    gridcoin/scraper/scraper_net.cpp
    gridcoin/scraper/scraper_registry.cpp
    gridcoin/sidestake.cpp
    gridcoin/staking/difficulty.cpp
    gridcoin/staking/exceptions.cpp
    gridcoin/staking/kernel.cpp
    gridcoin/staking/reward.cpp
    gridcoin/staking/status.cpp
    gridcoin/superblock.cpp
    gridcoin/support/block_finder.cpp
    gridcoin/tally.cpp
    gridcoin/tx_message.cpp
    gridcoin/upgrade.cpp
    gridcoin/voting/builders.cpp
    gridcoin/voting/claims.cpp
    gridcoin/voting/poll.cpp
    gridcoin/voting/registry.cpp
    gridcoin/voting/result.cpp
    gridcoin/voting/vote.cpp
    hash.cpp
    init.cpp
    key.cpp
    key_io.cpp
    keystore.cpp
    logging.cpp
    main.cpp
    miner.cpp
    net.cpp
    netaddress.cpp
    netbase.cpp
    node/blockstorage.cpp
    node/orphan_blocks.cpp
    node/ui_interface.cpp
    noui.cpp
    pbkdf2.cpp
    policy/policy.cpp
    primitives/transaction.cpp
    protocol.cpp
    pubkey.cpp
    random.cpp
    randomenv.cpp
    rpc/blockchain.cpp
    rpc/htlc.cpp
    rpc/client.cpp
    rpc/dataacq.cpp
    rpc/mining.cpp
    rpc/misc.cpp
    rpc/net.cpp
    rpc/protocol.cpp
    rpc/rawtransaction.cpp
    rpc/server.cpp
    rpc/voting.cpp
    scheduler.cpp
    script.cpp
    scrypt.cpp
    support/cleanse.cpp
    support/lockedpool.cpp
    sync.cpp
    uint256.cpp
    util.cpp
    util/bip32.cpp
    util/settings.cpp
    util/strencodings.cpp
    util/string.cpp
    util/syserror.cpp
    util/system.cpp
    util/threadinterrupt.cpp
    util/threadnames.cpp
    util/time.cpp
    util/tokenpipe.cpp
    validation.cpp
    wallet/db.cpp
    wallet/diagnose.cpp
    wallet/rpcdump.cpp
    wallet/rpcwallet.cpp
    wallet/wallet.cpp
    wallet/walletdb.cpp
    wallet/walletutil.cpp
)

if(USE_ASM_SCRYPT)
    target_sources(gridcoin_util PRIVATE scrypt-x86.S scrypt-x86_64.S)
endif()

target_include_directories(gridcoin_util PUBLIC
    ${CMAKE_SOURCE_DIR}/src
    ${CMAKE_BINARY_DIR}/src
)

target_link_libraries(gridcoin_util PUBLIC
    ${LIBBDB_CXX} ${LIBLEVELDB} ${LIBSECP256K1} ${LIBUNIVALUE}
    Boost::boost Boost::filesystem Boost::iostreams Boost::thread Boost::date_time Boost::serialization
    CURL::libcurl
    OpenSSL::Crypto OpenSSL::SSL
    Threads::Threads
    libzip::zip
    ZLIB::ZLIB
)

if(UNIX)
    target_link_libraries(gridcoin_util PUBLIC -lm ${ATOMICS_LIBRARIES} ${RT_LIBRARIES})
endif()

target_link_libraries(gridcoin_util PUBLIC ${LIBGRIDCOIN_CRYPTO})

if(WIN32)
    target_link_libraries(gridcoin_util PUBLIC
        wsock32
        ws2_32
        wldap32
        crypt32
        bcrypt
        shlwapi
        iphlpapi
        )
endif()

target_compile_definitions(gridcoin_util PUBLIC
    HAVE_CONFIG_H
    HAVE_BUILD_INFO
    CURL_STATICLIB
)

if(ENABLE_UPNP)
    if(DEFAULT_UPNP)
        target_compile_definitions(gridcoin_util PRIVATE USE_UPNP=1)
    else()
        target_compile_definitions(gridcoin_util PRIVATE USE_UPNP=0)
    endif()

    if(WIN32)
        target_compile_definitions(gridcoin_util PRIVATE MINIUPNP_STATICLIB)
    endif()

    target_link_libraries(gridcoin_util PUBLIC ${LIBMINIUPNPC})
endif()

if(ENABLE_DEBUG_LOCKORDER)
    target_compile_definitions(gridcoin_util PUBLIC DEBUG_LOCKORDER)
endif()

# Daemon
# ======

if(ENABLE_DAEMON)
    add_executable(gridcoinresearchd gridcoinresearchd.cpp)
    target_include_directories(gridcoinresearchd PRIVATE ${CMAKE_BINARY_DIR})
    target_compile_definitions(gridcoinresearchd PRIVATE CURL_STATICLIB) # <--- ADDED

    # Link gridcoinresearchd to gridcoin_util AND all of gridcoin_util's
    # dependencies, because it is a static library.
    target_link_libraries(gridcoinresearchd PUBLIC
        ${RUNTIME_LIBS}
        gridcoin_util

        # Dependencies of gridcoin_util
        ${LIBBDB_CXX} ${LIBLEVELDB} ${LIBSECP256K1} ${LIBUNIVALUE}
        Boost::boost Boost::filesystem Boost::iostreams Boost::thread Boost::date_time Boost::serialization
        CURL::libcurl
        OpenSSL::Crypto OpenSSL::SSL
        Threads::Threads
        libzip::zip
        ZLIB::ZLIB
    )

    if(WIN32)
        # Link the windows-specific libs
        target_link_libraries(gridcoinresearchd PUBLIC wsock32 ws2_32)

        target_sources(gridcoinresearchd PRIVATE gridcoinresearchd-res.rc)
        set_source_files_properties(gridcoinresearchd-res.rc PROPERTIES
            COMPILE_FLAGS "-I${CMAKE_BINARY_DIR}"
            COMPILE_DEFINITIONS WINDRES_PREPROC
        )
    endif()

    if(UNIX)
        # Link the unix-specific libs
        target_link_libraries(gridcoinresearchd PUBLIC
            -lm ${ATOMICS_LIBRARIES} ${RT_LIBRARIES}
        )
    endif()

    set_target_properties(gridcoinresearchd PROPERTIES
        RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
    )

    # Installation
    if(UNIX AND NOT APPLE)
        include(GNUInstallDirs)
        install(TARGETS gridcoinresearchd COMPONENT daemon
            DESTINATION "${CMAKE_INSTALL_BINDIR}"
        )
        install(FILES "${CMAKE_SOURCE_DIR}/doc/gridcoinresearchd.1" COMPONENT daemon
            DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
        )
        install(FILES "${CMAKE_SOURCE_DIR}/contrib/init/gridcoinresearchd.service" COMPONENT daemon
            DESTINATION "lib/systemd/system"
        )
        install(FILES "${CMAKE_SOURCE_DIR}/contrib/completions/bash/gridcoinresearchd.bash" COMPONENT daemon
            DESTINATION "${CMAKE_INSTALL_DATADIR}/bash-completion/completions"
            RENAME "gridcoinresearchd"
        )
    else()
        install(TARGETS gridcoinresearchd COMPONENT daemon
            RUNTIME DESTINATION bin
            BUNDLE  DESTINATION "."
        )
    endif()
endif()

# Qt GUI
# ======

if(ENABLE_GUI)
    add_subdirectory(qt)
endif()


# Tests
# =====

if(ENABLE_TESTS)
    add_subdirectory(test)
endif()
