cmake_minimum_required (VERSION 3.20)

project (bossdk
    VERSION 0.8.14
    LANGUAGES CXX
    DESCRIPTION "Baidu Object Storage C++ SDK")

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

option(ENABLE_EXAMPLE "Enable example" OFF)

set( MAIN_SRCS
    src/auth/auth.cpp
    src/bos/client.cpp
    src/bos/client_impl.cpp
    src/bos/sts_client.cpp
    src/bos/model/acl_data.cpp
    src/bos/model/bucket_meta_data.cpp
    src/bos/model/bucket_cors.cpp
    src/bos/model/bucket_inventory.cpp
    src/bos/model/bucket_request_payment.cpp
    src/bos/model/bucket_mirroring.cpp
    src/bos/model/bucket_tagging.cpp
    src/bos/model/bucket_lifecycle.cpp
    src/bos/model/bucket_copyright_protection.cpp
    src/bos/model/bucket_object_lock.cpp
    src/bos/model/user_quota_meta_data.cpp
    src/bos/model/copy_request.cpp
    src/bos/model/notification.cpp
    src/bos/model/object_meta_data.cpp
    src/bos/model/object_request.cpp
    src/bos/model/replication_rule.cpp
    src/bos/model/upload_request.cpp
    src/bos/request/complete_multipart_upload_request.cpp
    src/bos/request/delete_multi_objects_request.cpp
    src/bos/request/post_object_request.cpp
    src/bos/request/put_bucket_logging_request.cpp
    src/bos/request/put_bucket_replication_request.cpp
    src/bos/request/put_bucket_encryption_request.cpp
    src/bos/request/put_bucket_static_website_request.cpp
    src/bos/request/put_bucket_request.cpp
    src/bos/request/rename_object_request.cpp
    src/bos/response/append_object_response.cpp
    src/bos/response/complete_multipart_upload_response.cpp
    src/bos/response/copy_object_response.cpp
    src/bos/response/copy_part_response.cpp
    src/bos/response/delete_multi_objects_response.cpp
    src/bos/response/delete_object_response.cpp
    src/bos/response/fetch_object_response.cpp
    src/bos/response/get_bucket_acl_response.cpp
    src/bos/response/get_bucket_alias_response.cpp
    src/bos/response/get_bucket_cors_response.cpp
    src/bos/response/get_bucket_inventory_response.cpp
    src/bos/response/list_bucket_inventory_response.cpp
    src/bos/response/get_bucket_request_payment_response.cpp
    src/bos/response/get_bucket_mirroring_response.cpp
    src/bos/response/get_bucket_tagging_response.cpp
    src/bos/response/get_bucket_lifecycle_response.cpp
    src/bos/response/get_bucket_copyright_protection_response.cpp
    src/bos/response/get_bucket_object_lock_response.cpp
    src/bos/response/get_bucket_location_response.cpp
    src/bos/response/get_bucket_logging_response.cpp
    src/bos/response/get_bucket_encryption_response.cpp
    src/bos/response/get_bucket_static_website_response.cpp
    src/bos/response/get_notification_response.cpp
    src/bos/response/get_bucket_quota_response.cpp
    src/bos/response/get_bucket_replication_progress_response.cpp
    src/bos/response/get_bucket_replication_response.cpp
    src/bos/response/get_user_quota_response.cpp
    src/bos/response/get_bucket_storage_class_response.cpp
    src/bos/response/get_bucket_trash_response.cpp
    src/bos/response/get_bucket_versioning_response.cpp
    src/bos/response/get_object_acl_response.cpp
    src/bos/response/get_object_response.cpp
    src/bos/response/get_object_tagging_response.cpp
    src/bos/response/init_multi_upload_response.cpp
    src/bos/response/list_buckets_response.cpp
    src/bos/response/list_bucket_replication_response.cpp
    src/bos/response/list_multipart_uploads_response.cpp
    src/bos/response/list_object_versions_response.cpp
    src/bos/response/list_objects_response.cpp
    src/bos/response/list_parts_response.cpp
    src/bos/sts_response/assume_role_response.cpp
    src/http/http_client.cpp
    src/http/http_epoll_reactor.cpp
    src/http/http_request.cpp
    src/http/http_response.cpp
    src/model/bce_request.cpp
    src/model/bce_response.cpp
    src/model/json_response.cpp
    src/util/rate_limiter.cpp
    src/util/util.cpp
)

if(WIN32)
    set( WIN_SRCS
        src/util/win_crypto_impl.cpp
        src/util/windows_port.cpp
    )
else()
    set( LINUX_SRCS
        src/util/openssl_crypto_impl.cpp
    )
endif()

if(WIN32)
    if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/thirdlib/curl)
        file(ARCHIVE_EXTRACT
            INPUT ${CMAKE_CURRENT_SOURCE_DIR}/thirdlib/windows_dependency.zip
            DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/thirdlib
        )
    endif()

    include_directories(
        include
        thirdlib/curl/include
        thirdlib/win_uuid/include
    )

    set(ARCHITECTURE, "")
    if("${CMAKE_GENERATOR}" MATCHES "(Win64|AMD64)")
        set(ARCHITECTURE "x64")
        list( APPEND LIBS thirdlib/curl/bin/AMD64/LIBCURL.LIB )
    elseif("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
        set(ARCHITECTURE "IA64")
        list( APPEND LIBS thirdlib/curl/bin/IA64/LIBCURL.LIB )
    elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
        set(ARCHITECTURE "x86")
        list( APPEND LIBS thirdlib/curl/bin/I386/LIBCURL.LIB )
    endif()

    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/output/lib/${ARCHITECTURE}")
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/output/lib/${ARCHITECTURE}")
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/output/lib/${ARCHITECTURE}")

    file(COPY ${CMAKE_SOURCE_DIR}/include/
        DESTINATION "${CMAKE_SOURCE_DIR}/output/include")

    macro(SET_OPTION option value)
    set(${option} ${value} CACHE INTERNAL "" FORCE)
    endmacro()

    SET_OPTION(JSONCPP_WITH_TESTS OFF)
    SET_OPTION(JSONCPP_WITH_POST_BUILD_UNITTEST OFF)
    add_subdirectory(thirdlib/json)

    add_library(bossdk ${MAIN_SRCS} ${WIN_SRCS} ${LIBS})
    target_link_libraries (bossdk jsoncpp_lib_static)

    if("${CMAKE_GENERATOR}" MATCHES "(Win64|AMD64)")
        add_custom_command(TARGET bossdk POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/thirdlib/curl/bin/AMD64/LIBCURL.DLL"
                "${CMAKE_SOURCE_DIR}/output/lib/x64/$<CONFIG>"
            COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/thirdlib/curl/bin/AMD64/LIBCURL.LIB"
                "${CMAKE_SOURCE_DIR}/output/lib/x64/$<CONFIG>"
        )
    elseif("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
        add_custom_command(TARGET bossdk POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/thirdlib/curl/bin/IA64/LIBCURL.DLL"
                "${CMAKE_SOURCE_DIR}/output/lib/IA64/$<CONFIG>"
            COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/thirdlib/curl/bin/IA64/LIBCURL.LIB"
                "${CMAKE_SOURCE_DIR}/output/lib/IA64/$<CONFIG>"
        )
    elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
        add_custom_command(TARGET bossdk POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/thirdlib/curl/bin/I386/LIBCURL.DLL"
                "${CMAKE_SOURCE_DIR}/output/lib/x86/$<CONFIG>"
            COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/thirdlib/curl/bin/I386/LIBCURL.LIB"
                "${CMAKE_SOURCE_DIR}/output/lib/x86/$<CONFIG>"
        )
    endif()
else()
    find_package(PkgConfig REQUIRED)
    find_package(CURL REQUIRED)
    find_package(OpenSSL REQUIRED COMPONENTS SSL Crypto)
    pkg_check_modules(UUID REQUIRED uuid)

    set(JSONCPP_WITH_TESTS OFF CACHE BOOL "" FORCE)
    set(JSONCPP_WITH_POST_BUILD_UNITTEST OFF CACHE BOOL "" FORCE)
    add_subdirectory(thirdlib/json)
    include_directories(include)

    add_library(bossdk ${MAIN_SRCS} ${LINUX_SRCS})
    target_link_libraries(bossdk PRIVATE jsoncpp_lib_static CURL::libcurl OpenSSL::SSL OpenSSL::Crypto uuid)

    set(LIBRARY_INSTALL_DIR "lib" CACHE PATH "Library installation directory")
    set(INCLUDE_INSTALL_DIR "include" CACHE PATH "Header installation directory")

    target_include_directories(bossdk PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>)

    install(DIRECTORY include/bcesdk DESTINATION include FILES_MATCHING PATTERN "*.h")

    install(TARGETS bossdk ${INSTALL_EXPORT}
        LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR}
        INCLUDES DESTINATION ${INCLUDE_INSTALL_DIR})
endif()

target_compile_definitions(bossdk PRIVATE
    VERSION="${PROJECT_VERSION}"
)

if(ENABLE_EXAMPLE)
    add_subdirectory(example)
endif()
