project(oiofs CXX C)
cmake_minimum_required(VERSION 2.8)

# Helper functions and macros
include(cmake/helper.cmake)

config_compiler_and_linker()

if(LD_LIBDIR)
    MESSAGE("Setting LD_LIBDIR to: ${LD_LIBDR}")
else()
    set(LD_LIBDIR "lib64")
    MESSAGE("Setting LD_LIBDIR to default value: ${LD_LIBDIR}")
endif()

include_directories(
    ${oiofs_SOURCE_DIR}
    ${oiofs_SOURCE_DIR}/include
    ${oiofs_BINARY_DIR})

find_program(PROTOC_EXECUTABLE protoc)
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin)

find_package(PkgConfig)

pkg_check_modules(PROTOBUF protobuf)
pkg_check_modules(GRPC grpc)
pkg_check_modules(GRPCXX grpc++)
pkg_check_modules(GPR gpr)
pkg_check_modules(HIREDIS hiredis)
pkg_check_modules(FUSE fuse)
pkg_check_modules(GLOG libglog)

## oiocore & oiosds
pkg_check_modules(GLIB2 glib-2.0)
find_library(OIOSDS_LIBRARIES oiosds ${OIOSDS_LIBDIR})
find_library(OIOCORE_LIBRARIES oiocore ${OIOSDS_LIBDIR})
include_directories(
	${OIOSDS_INCDIR}
	${GLIB2_INCLUDE_DIRS})
MESSAGE("include: ${OIOSDS_INCDIR}")
if(OIOSDS_LIBRARIES-NOTFOUND)
	MESSAGE(FATAL_ERROR "oiosds not found")
endif()
if(OIOCORE_LIBRARIES-NOTFOUND)
	MESSAGE(FATAL_ERROR "oiocore not found")
endif()


add_custom_command(
    DEPENDS ${oiofs_SOURCE_DIR}/protos/meta.proto
    OUTPUT meta.pb.cc
    COMMAND ${PROTOC_EXECUTABLE} -I ${oiofs_SOURCE_DIR}/protos
    --cpp_out=${oiofs_BINARY_DIR}
    ${oiofs_SOURCE_DIR}/protos/meta.proto)

add_custom_command(
    DEPENDS ${oiofs_SOURCE_DIR}/protos/meta.proto
    OUTPUT meta.grpc.pb.cc
    COMMAND ${PROTOC_EXECUTABLE} -I ${oiofs_SOURCE_DIR}/protos
    --grpc_out=${oiofs_BINARY_DIR}
    --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN}
    ${oiofs_SOURCE_DIR}/protos/meta.proto)

add_library(meta_client STATIC src/meta/client.cc
    src/page_list.cc
    src/file_cache.cc
    src/inode.cc
    ${oiofs_BINARY_DIR}/meta.grpc.pb.cc
    ${oiofs_BINARY_DIR}/meta.pb.cc)
set_target_properties(meta_client
    PROPERTIES
    COMPILE_FLAGS "${cxx_strict}")
target_link_libraries(meta_client
    ${GRPCXX_LIBRARIES} ${GRPC_LIBRARIES} ${GPR_LIBRARIES}
    ${GLOG_LIBRARIES} ${GLIB2_LIBRARIES}
    ${OIOSDS_LIBRARIES} ${OIOCORE_LIBRARIES} ${PROTOBUF_LIBRARIES})

add_library(meta_server STATIC src/meta/server.cc
    src/meta/backend.cc
    src/meta/server_builder.cc
    src/meta/service.cc
    ${oiofs_BINARY_DIR}/meta.grpc.pb.cc
    ${oiofs_BINARY_DIR}/meta.pb.cc)
set_target_properties(meta_server
    PROPERTIES
    COMPILE_FLAGS "${cxx_strict}")
target_link_libraries(meta_server
    ${GRPCXX_LIBRARIES} ${GRPC_LIBRARIES} ${GPR_LIBRARIES}
    ${PROTOBUF_LIBRARIES} ${HIREDIS_LIBRARIES}
	${GLOG_LIBRARIES})

cxx_executable(oiofs_server src/meta "meta_server;${OIOSDS_LIBRARIES};${OIOCORE_LIBRARIES}")

cxx_shared_library(oiofs "${cxx_strict}" src/oiofs.cc)
target_link_libraries(oiofs meta_client)

cxx_executable(oiofs_fuse src/fuse "${FUSE_LIBRARIES};oiofs")
target_compile_options(oiofs_fuse PUBLIC ${FUSE_CFLAGS})

cxx_executable(mkfs.oiofs src/mkfs "meta_client")

install(TARGETS oiofs_server oiofs_fuse oiofs mkfs.oiofs
	LIBRARY DESTINATION ${LD_LIBDIR}
	RUNTIME DESTINATION bin)

## Google Test Build

set(gtest_SOURCE_DIR "${oiofs_SOURCE_DIR}/third_party/googletest")
set(gtest_BINARY_DIR "${oiofs_BINARY_DIR}/third_party/googletest")

# gtest include dir
include_directories(
    ${gtest_SOURCE_DIR}/include
    ${gtest_SOURCE_DIR})

# gtest libs
link_directories(${gtest_BINARY_DIR}/src)

find_package(Threads)

cxx_shared_library(gtest "${cxx_strict}" ${gtest_SOURCE_DIR}/src/gtest-all.cc)
set_target_properties(gtest PROPERTIES COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1")
target_link_libraries(gtest ${CMAKE_THREAD_LIBS_INIT})

cxx_shared_library(gtest_main "${cxx_strict}" ${gtest_SOURCE_DIR}/src/gtest_main.cc)
set_target_properties(gtest_main PROPERTIES COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1")
target_link_libraries(gtest_main ${CMAKE_THREAD_LIBS_INIT})

target_link_libraries(gtest_main gtest)

enable_testing()

## Tests

## cxx_test(oiofs_test test/oiofs "gtest_main;oiofs")
cxx_test(test_client test/oiofs/meta "gtest_main;oiofs")
