cmake_minimum_required(VERSION 3.16)
project(otpclient LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

option(OTPCLIENT_BUILD_TESTS "Build OTP Client regression tests" OFF)

if(OTPCLIENT_BUILD_TESTS AND NOT DEFINED ENV{ARCH_TRIPLET})
   find_package(Qt5 REQUIRED COMPONENTS Core Test)
   find_package(OpenSSL REQUIRED COMPONENTS Crypto)

   enable_testing()
   add_executable(
      otpclient_tests
      tests/test_otpclient.cpp
      src/AppPaths.cpp
      src/AppPaths.h
      src/Crypto.cpp
      src/Crypto.h
      src/OtpEngine.cpp
      src/OtpEngine.h
      src/SettingsStore.cpp
      src/SettingsStore.h
      src/VaultBackend.cpp
      src/VaultBackend.h
   )
   target_include_directories(otpclient_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
   target_compile_definitions(otpclient_tests PRIVATE OTPCLIENT_TESTING=1)
   target_link_libraries(
      otpclient_tests
      PRIVATE
      Qt5::Core
      Qt5::Test
      OpenSSL::Crypto
   )
   add_test(NAME otpclient_tests COMMAND otpclient_tests)
   return()
endif()

find_package(Qt5 REQUIRED COMPONENTS Core Gui Multimedia Qml Quick)
find_package(OpenSSL REQUIRED COMPONENTS Crypto)
find_package(ZXing 2.2 REQUIRED)

if(NOT DEFINED ENV{ARCH_TRIPLET})
   message(FATAL_ERROR "ARCH_TRIPLET is not set. Build this project with Clickable, or use -DOTPCLIENT_BUILD_TESTS=ON for host tests.")
endif()

set(ARCH "$ENV{ARCH}")
set(ARCH_TRIPLET "$ENV{ARCH_TRIPLET}")
set(CLICK_FRAMEWORK "$ENV{CLICK_FRAMEWORK}")
set(APPARMOR_POLICY "$ENV{APPARMOR_POLICY}")

configure_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/manifest.json.in
   ${CMAKE_CURRENT_BINARY_DIR}/manifest.json
   @ONLY
)

configure_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/otpclient.apparmor.in
   ${CMAKE_CURRENT_BINARY_DIR}/otpclient.apparmor
   @ONLY
)

qt5_add_resources(APP_RESOURCES resources.qrc)

add_executable(
   otpclient
   src/main.cpp
   src/AppPaths.cpp
   src/AppPaths.h
   src/BackupManager.cpp
   src/BackupManager.h
   src/Crypto.cpp
   src/Crypto.h
   src/OtpEngine.cpp
   src/OtpEngine.h
   src/QrDecoder.cpp
   src/QrDecoder.h
   src/SettingsStore.cpp
   src/SettingsStore.h
   src/VaultBackend.cpp
   src/VaultBackend.h
   ${APP_RESOURCES}
)

target_link_libraries(
   otpclient
   PRIVATE
   Qt5::Core
   Qt5::Gui
   Qt5::Multimedia
   Qt5::Qml
   Qt5::Quick
   OpenSSL::Crypto
   ZXing::ZXing
)

set_target_properties(otpclient PROPERTIES INSTALL_RPATH "$ORIGIN/..")

install(
   TARGETS otpclient
   RUNTIME DESTINATION lib/${ARCH_TRIPLET}/bin
)

# ZXing-C++ is a build-time package in the Clickable container but is not
# guaranteed to be part of the Ubuntu Touch framework. Follow the shared-library
# symlink chain so both the SONAME link and its real target are staged in the Click.
install(CODE "
   file(COPY \"$<TARGET_FILE:ZXing::ZXing>\"
      DESTINATION \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/lib/${ARCH_TRIPLET}\"
      FOLLOW_SYMLINK_CHAIN
   )
")

install(
   FILES
   ${CMAKE_CURRENT_BINARY_DIR}/manifest.json
   ${CMAKE_CURRENT_BINARY_DIR}/otpclient.apparmor
   ${CMAKE_CURRENT_SOURCE_DIR}/otpclient.desktop
   ${CMAKE_CURRENT_SOURCE_DIR}/otpclient.contenthub
   DESTINATION .
)

install(
   DIRECTORY assets
   DESTINATION .
)

install(
   FILES
   ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE
   ${CMAKE_CURRENT_SOURCE_DIR}/README.md
   ${CMAKE_CURRENT_SOURCE_DIR}/THIRD-PARTY.md
   ${CMAKE_CURRENT_SOURCE_DIR}/OPENSTORE-DESCRIPTION.txt
   ${CMAKE_CURRENT_SOURCE_DIR}/CHANGELOG.md
   DESTINATION share/otpclient
)

install(
   FILES ${CMAKE_CURRENT_SOURCE_DIR}/licenses/ZXing-Cpp-Apache-2.0.txt
   DESTINATION share/otpclient/licenses
)

if(OTPCLIENT_BUILD_TESTS)
   enable_testing()
   find_package(Qt5 REQUIRED COMPONENTS Test)

   add_executable(
      otpclient_tests
      tests/test_otpclient.cpp
      src/AppPaths.cpp
      src/AppPaths.h
      src/Crypto.cpp
      src/Crypto.h
      src/OtpEngine.cpp
      src/OtpEngine.h
      src/SettingsStore.cpp
      src/SettingsStore.h
      src/VaultBackend.cpp
      src/VaultBackend.h
   )
   target_include_directories(otpclient_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
   target_compile_definitions(otpclient_tests PRIVATE OTPCLIENT_TESTING=1)
   target_link_libraries(
      otpclient_tests
      PRIVATE
      Qt5::Core
      Qt5::Test
      OpenSSL::Crypto
   )
   add_test(NAME otpclient_tests COMMAND otpclient_tests)
endif()
