set(Shadow_LINKER_LIBS)

set(Shadow_INSTALL_INCLUDE_PREFIX include)
set(Shadow_INSTALL_LIB_PREFIX lib)
set(Shadow_INSTALL_BIN_PREFIX bin)

if (${USE_CUDA})
  find_package(CUDA)
  if (CUDA_FOUND)
    include(cmake/Cuda.cmake)
    set(CUDA_PROPAGATE_HOST_FLAGS ON)
    select_nvcc_arch_flags(NVCC_FLAGS_EXTRA)
    list(APPEND CUDA_NVCC_FLAGS ${NVCC_FLAGS_EXTRA})
    include_directories(SYSTEM ${CUDA_INCLUDE_DIRS})
    list(APPEND Shadow_LINKER_LIBS ${CUDA_LIBRARIES} ${CUDA_cublas_LIBRARY})
    message(STATUS "Added CUDA NVCC flags: ${NVCC_FLAGS_EXTRA}")
    add_definitions(-DUSE_CUDA)
    if (${USE_CUDNN})
      find_package(CUDNN QUIET)
      if (CUDNN_FOUND)
        include_directories(SYSTEM ${CUDNN_INCLUDE_DIRS})
        list(APPEND Shadow_LINKER_LIBS ${CUDNN_LIBRARIES})
        message(STATUS "Found CUDNN: ${CUDNN_INCLUDE_DIRS}, ${CUDNN_LIBRARIES} (found version ${CUDNN_VERSION})")
        add_definitions(-DUSE_CUDNN)
      else ()
        set(USE_CUDNN OFF)
        message(WARNING "Could not find CUDNN, disable it")
      endif ()
    endif ()
  else ()
    set(USE_CUDA OFF)
    message(WARNING "Could not find CUDA, disable it")
  endif ()
endif ()

if (${USE_Eigen})
  find_package(Eigen)
  if (NOT Eigen_FOUND)
    message(STATUS "Could not find eigen library, build it from source")
    download_external("${PROJECT_SOURCE_DIR}/cmake/external/DownloadEigen.cmake"
                      "${CMAKE_BINARY_DIR}/eigen-download")
    find_package(Eigen)
  endif ()
  if (Eigen_FOUND)
    include_directories(SYSTEM ${Eigen_INCLUDE_DIRS})
    add_definitions(-DUSE_Eigen)
  else ()
    set(USE_Eigen OFF)
    message(WARNING "Could not find Eigen, disable it")
  endif ()
endif ()

if (${USE_BLAS})
  if (${BLAS} STREQUAL "OpenBLAS" OR ${BLAS} STREQUAL "openblas")
    find_package(OpenBLAS QUIET)
    if (OpenBLAS_FOUND)
      include_directories(SYSTEM ${OpenBLAS_INCLUDE_DIRS})
      list(APPEND Shadow_LINKER_LIBS ${OpenBLAS_LIBRARIES})
      message(STATUS "Found OpenBLAS: ${OpenBLAS_INCLUDE_DIRS}, ${OpenBLAS_LIBRARIES} (found version ${OpenBLAS_VERSION})")
      add_definitions(-DUSE_OpenBLAS)
    else ()
      set(USE_BLAS OFF)
      message(WARNING "Could not find OpenBLAS, disable it")
    endif ()
  elseif (${BLAS} STREQUAL "MKL" OR ${BLAS} STREQUAL "mkl")
    find_package(MKL QUIET)
    if (MKL_FOUND)
      include_directories(SYSTEM ${MKL_INCLUDE_DIRS})
      list(APPEND Shadow_LINKER_LIBS ${MKL_LIBRARIES})
      message(STATUS "Found MKL: ${MKL_INCLUDE_DIRS}, ${MKL_LIBRARIES} (found version ${MKL_VERSION})")
      add_definitions(-DUSE_MKL)
    else ()
      set(USE_BLAS OFF)
      message(WARNING "Could not find MKL, disable it")
    endif ()
  endif ()
endif ()

if (${USE_NNPACK})
  find_package(NNPACK QUIET)
  if (NOT NNPACK_FOUND)
    message(STATUS "Could not find nnpack library, build it from source")
    download_external("${PROJECT_SOURCE_DIR}/cmake/external/DownloadNNPACK.cmake"
                      "${CMAKE_BINARY_DIR}/nnpack-download")
    find_package(NNPACK QUIET)
  endif ()
  if (NNPACK_FOUND)
    include_directories(SYSTEM ${NNPACK_INCLUDE_DIRS})
    list(APPEND Shadow_LINKER_LIBS ${NNPACK_LIBRARIES})
    message(STATUS "Found NNPACK: ${NNPACK_INCLUDE_DIRS}, ${NNPACK_LIBRARIES}")
    add_definitions(-DUSE_NNPACK)
  else ()
    set(USE_NNPACK OFF)
    message(WARNING "Could not find NNPACK, disable it")
  endif ()
endif ()

if (${USE_DNNL})
  find_package(DNNL QUIET)
  if (NOT DNNL_FOUND)
    message(STATUS "Could not find dnnl library, build it from source")
    download_external("${PROJECT_SOURCE_DIR}/cmake/external/DownloadDNNL.cmake"
                      "${CMAKE_BINARY_DIR}/dnnl-download")
    find_package(DNNL QUIET)
  endif ()
  if (DNNL_FOUND)
    include_directories(SYSTEM ${DNNL_INCLUDE_DIRS})
    list(APPEND Shadow_LINKER_LIBS ${DNNL_LIBRARIES})
    message(STATUS "Found DNNL: ${DNNL_INCLUDE_DIRS}, ${DNNL_LIBRARIES} (found version ${DNNL_VERSION})")
    add_definitions(-DUSE_DNNL)
  else ()
    set(USE_DNNL OFF)
    message(WARNING "Could not find DNNL, disable it")
  endif ()
endif ()

if (${USE_Protobuf})
  find_package(Protobuf QUIET)
  if (Protobuf_FOUND)
    include(cmake/ProtoBuf.cmake)
    message(STATUS "Found Protobuf: ${Protobuf_INCLUDE_DIRS}, ${Protobuf_LIBRARIES} (found version ${Protobuf_VERSION})")
    message(STATUS "Found Protoc: ${Protoc_EXECUTABLE} (found version ${Protoc_VERSION})")
    add_definitions(-DUSE_Protobuf)
  else ()
    set(USE_Protobuf OFF)
    message(WARNING "Could not find Protobuf, disable it")
  endif ()
endif ()

if (${USE_JSON})
  find_package(RapidJSON)
  if (NOT RapidJSON_FOUND)
    message(STATUS "Could not find rapidjson library, build it from source")
    download_external("${PROJECT_SOURCE_DIR}/cmake/external/DownloadRapidJSON.cmake"
                      "${CMAKE_BINARY_DIR}/rapidjson-download")
    find_package(RapidJSON)
  endif ()
  if (RapidJSON_FOUND)
    include_directories(SYSTEM ${RapidJSON_INCLUDE_DIRS})
    add_definitions(-DUSE_JSON)
  else ()
    set(USE_JSON OFF)
    message(WARNING "Could not find RapidJSON, disable it")
  endif ()
endif ()

if (${USE_OpenCV})
  find_package(OpenCV PATHS ${OpenCV_DIR} NO_DEFAULT_PATH QUIET COMPONENTS core highgui imgproc imgcodecs videoio)
  if (NOT OpenCV_FOUND) # if not OpenCV 3.x, then try to find OpenCV 2.x in default path
    find_package(OpenCV REQUIRED QUIET COMPONENTS core highgui imgproc)
  endif ()
  if (${OpenCV_VERSION} VERSION_GREATER "2.4.13")
    find_package(OpenCV REQUIRED QUIET COMPONENTS core highgui imgproc imgcodecs videoio)
  endif ()
  message(STATUS "Found OpenCV: ${OpenCV_CONFIG_PATH} (found version ${OpenCV_VERSION})")
endif ()

if (UNIX)
  if (NOT APPLE AND NOT ANDROID)
    find_package(Threads QUIET)
    if (CMAKE_THREAD_LIBS_INIT)
      list(APPEND Shadow_LINKER_LIBS ${CMAKE_THREAD_LIBS_INIT})
    else ()
      message(FATAL_ERROR "Could not find threads")
    endif ()
  endif ()
endif ()
