project(cppKin CXX)
cmake_minimum_required(VERSION 3.5)

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

if(NOT WIN32)
    string(ASCII 27 Esc)
    set(ColourReset "${Esc}[m")
    set(Red "${Esc}[31m")
    set(Green "${Esc}[32m")
else()
    set(ColourReset "")
    set(Red "")
    set(Green "")
endif()

if (NOT CMAKE_BUILD_TYPE)
    message(STATUS "Default build type 'Debug'")
    set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE )
endif()

if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
    set(CMAKE_DEBUG_POSTFIX d)
endif()
if(NOT PYTHON_BINDING)
    set(PYTHON_BINDING "pyBind")
endif()
option(3RD_PARTY_INSTALL_STEP "3rd party install step" OFF)
option(PRE_COMPILE_STEP "Pre compile step" OFF)
option(COMPILATION_STEP "Compile step" OFF)
option(WITH_THRIFT "Thrift transportation is supported" OFF)
option(WITH_TESTS "with tests" OFF)
option(WITH_EXAMPLES "with examples" OFF)
option(WITH_PYTHON "with python" OFF)
option(FORCE_INSTALL_RPATH "install rpath" OFF)
if(WITH_TESTS)
	set(WITH_PYTHON ON)
endif()

set(CPPKIN_DEPEND_LIST "")
set(CPPKIN_WRAPPER_DEPEND_LIST "")

set(PROJECT_SOURCE_DIR ${CMAKE_SOURCE_DIR})
set(PROJECT_BUILD_DIR ${CMAKE_BINARY_DIR})
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
if(NOT PROJECT_3RD_LOC)
    set(PROJECT_3RD_LOC ${PROJECT_BINARY_DIR}/Third_Party)
endif()
if(NOT VC_VERSION)
    set(VC_VERSION 12)
endif()
if(WIN32)
	message(STATUS "Visual version - ${VC_VERSION}")
endif()

if(NOT IS_ABSOLUTE ${PROJECT_3RD_LOC})
    get_filename_component(PROJECT_3RD_LOC ${PROJECT_3RD_LOC} ABSOLUTE BASE_DIR ${PROJECT_SOURCE_DIR})
endif()
string(FIND "${CMAKE_PREFIX_PATH}" "${PROJEC_3RD_LOC}" 3RD_LOC_PREFIX_ADDED)
if(NOT ${3RD_LOC_PREFIX_ADDED})
    list(APPEND CMAKE_PREFIX_PATH ${PROJECT_3RD_LOC})
endif()

if(3RD_PARTY_INSTALL_STEP)
    message(STATUS "third party installation path - ${PROJECT_3RD_LOC}")
    message(STATUS "python binding lib - ${PYTHON_BINDING}")
    find_package(SpdLog)
    find_package(Boost_Pack)
    find_package(CURL)
    find_package(Core)
    find_package(RapidJson)
    if(WITH_PYTHON)
        find_package(Python)
        if(${PYTHON_BINDING} STREQUAL "sweetPy")
            find_package(SweetPy)
        elseif(${PYTHON_BINDING} STREQUAL "pyBind")
            find_package(PyBind)
        else()
            message(FATAL_ERROR "invalid binding library - ${PYTHON_BINDING}")
        endif()

        if(WITH_TESTS)
            find_package(Bottle)
        endif()
    endif()
	
	if(WITH_TESTS AND UNIX AND NOT APPLE)
		find_package(BenchMark)
     endif()
    include(installThirdParty)
endif()

include_directories(${PROJECT_SOURCE_DIR} ${PYTHON_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src ${PROJECT_3RD_LOC}/include)
link_directories(${PROJECT_3RD_LOC}/lib ${OUTPUT_DIR})

if(COMPILATION_STEP)
    message(STATUS "checking if tests supported - ${WITH_TESTS}")
    message(STATUS "checking if examples supported - ${WITH_EXAMPLES}")
	message(STATUS "checking if python supported - ${WITH_PYTHON}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DRAPID_JSON_FOUND")
    if(${FORCE_INSTALL_RPATH})
        set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
    endif()
    set(CMAKE_INSTALL_RPATH "$ORIGIN")
    set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
    if(NOT OUTPUT_DIR)
        set(OUTPUT_DIR ${PROJECT_BUILD_DIR})
    endif()
    if(NOT IS_ABSOLUTE ${OUTPUT_DIR})
        get_filename_component(OUTPUT_DIR ${OUTPUT_DIR} ABSOLUTE BASE_DIR ${PROJECT_BUILD_DIR})
    endif()
    message(STATUS "Output dir - ${OUTPUT_DIR}")
    add_definitions(-DCPPKIN_DLL)

    if(WIN32)
        add_definitions(-DCURL_STATICLIB)
        set(TO_LINK_LIBS libcurl Core${CMAKE_DEBUG_POSTFIX}.dll Ws2_32)
    else()
        set(TO_LINK_LIBS pthread curl libCore${CMAKE_DEBUG_POSTFIX}.so)
    endif()

    add_library(cppkin SHARED src/Trace.h src/SpanContainer.h src/SpanContainer.cpp src/span_impl.cpp src/span_impl.h src/AnnotationType.cpp src/AnnotationType.h src/Annotation.h src/SimpleAnnotation.cpp src/SimpleAnnotation.h src/cppkin.h src/Trace.cpp src/Encoder.cpp src/Encoder.h src/EncodingTypes.cpp src/EncodingTypes.h src/EncodingContext.cpp src/EncodingContext.h src/TransportManager.cpp src/TransportManager.h src/Transport.cpp src/Transport.h src/HttpTransport.cpp src/HttpTransport.h src/ConfigTags.h src/TransportType.cpp src/TransportType.h src/TransportFactory.h src/TransportFactory.cpp src/ConfigParams.cpp src/ConfigTags.cpp src/Annotation.cpp src/Sampler.cpp src/JsonEncoder.h src/cppkin.cpp src/Export.h src/Span.cpp src/Span.h src/BinaryAnnotation.cpp)
	if(CPPKIN_DEPEND_LIST)
		add_dependencies(cppkin ${CPPKIN_DEPEND_LIST})
	endif()
    set_target_properties(cppkin PROPERTIES PUBLIC_HEADER "src/Trace.h;src/Annotation.h;src/cppkin.h;src/Span.h;src/AnnotationType.h;src/BinaryAnnotation.h;src/ConfigParams.h;src/ConfigTags.h;src/Encoder.h;src/EncodingContext.h;src/EncodingTypes.h;src/Export.h;src/HttpTransport.h;src/JsonEncoder.h;src/Sampler.h;src/ScribeTransport.h;src/SimpleAnnotation.h;src/span_impl.h;src/StubTransport.h;src/ThriftEncoder.h;src/Transport.h;src/TransportFactory.h;src/TransportManager.h;src/TransportType.h")
	
	if(WITH_PYTHON)
		set(binderLib "")
		if(${PYTHON_BINDING} STREQUAL "sweetPy")
			set(binderLib libsweetPy${CMAKE_DEBUG_POSTFIX}.so)
			add_definitions(-DSWEETPY)
		else()
			add_definitions(-DPYBIND)
		endif()

		add_library(_cppkin SHARED src/cppkinWrapper.cpp)
		if(CPPKIN_WRAPPER_DEPEND_LIST)
			add_dependencies(_cppkin ${CPPKIN_WRAPPER_DEPEND_LIST})
		endif()
		target_link_libraries(_cppkin libCore${CMAKE_DEBUG_POSTFIX}.so ${binderLib} cppkin)
		set_target_properties(_cppkin PROPERTIES PREFIX "")
		set_target_properties(_cppkin PROPERTIES DEBUG_POSTFIX "")
	endif()

    if(WITH_THRIFT)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTHRIFT_FOUND")
        target_sources(cppkin PRIVATE src/ScribeTransport.cpp src/ScribeTransport.cpp src/ScribeTransport.h GeneratedFiles/scribe.cpp GeneratedFiles/Scribe_constants.cpp GeneratedFiles/Scribe_types.cpp GeneratedFiles/zipkinCore_constants.cpp GeneratedFiles/zipkinCore_types.cpp src/ThriftEncoder.h)
        if(WIN32)
            set(TO_LINK_LIBS "${TO_LINK_LIBS};thriftmd${CMAKE_DEBUG_POSTFIX}")
        else()
            set(TO_LINK_LIBS "${TO_LINK_LIBS};thrift")
        endif()
    endif()

    if(${SPDLOG_FOUND})
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSPDLOG_FOUND")
    endif()
    target_link_libraries(cppkin ${TO_LINK_LIBS})

    if(WITH_EXAMPLES)
        add_subdirectory(${PROJECT_SOURCE_DIR}/examples)
    endif()
    if(UNIX AND NOT APPLE AND WITH_TESTS)
        add_subdirectory(bench)
    endif()
	if(WIN32)
		install(TARGETS cppkin
				PUBLIC_HEADER DESTINATION ${OUTPUT_DIR}/include
				RUNTIME DESTINATION ${OUTPUT_DIR}/lib
				)
		install(DIRECTORY ${PROJECT_3RD_LOC}/lib
				DESTINATION ${OUTPUT_DIR}
				FILES_MATCHING PATTERN "*.dll" 
				)
	else()
		install(TARGETS cppkin
				PUBLIC_HEADER DESTINATION ${OUTPUT_DIR}/include
				LIBRARY DESTINATION ${OUTPUT_DIR}/lib
				)
        install(DIRECTORY ${PROJECT_3RD_LOC}/lib
                DESTINATION ${OUTPUT_DIR}
                FILES_MATCHING PATTERN "*.so"
                )
	endif()
endif()

if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -pedantic -Wno-sign-compare -Wno-unused-variable")
endif()
