cmake_minimum_required(VERSION 3.8.2...3.20)

set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
project(noson-app C CXX)

set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)

if((NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "None") AND NOT CMAKE_CONFIGURATION_TYPES)
    message(STATUS "Setting build type to 'Release' as none was specified.")
    set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
    # Set the possible values of build type for cmake-gui
    set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()

include(FeatureSummary)

option(INSTALL_TESTS "Install the tests on make install" OFF)

option(QT_VERSION_PREFERRED "preferred Qt version")
include(qtchooser)
if(NOT QT_FOUND)
    message(FATAL_ERROR "Qt NOT found")
endif()

if(IOS OR ANDROID)
    set(QT_STATICPLUGIN ON CACHE BOOL "Build static plugins" FORCE)
endif()

set(APP_VERSION       "5.7.2")
set(APP_VERSION_CODE  130)
set(APP_ID            "io.github.janbar.noson")
set(APP_NAME          "noson")

set(EXEC              "noson-app")
set(ICON_NAME         "${APP_NAME}")
set(APP_DESKTOP_ID    "${APP_ID}")

set(ICON_FILE         "noson.png")
set(DESKTOP_FILE_NAME "noson.desktop")
set(APPDATA_FILE_NAME "noson.appdata.xml")

# Components PATH
execute_process(
    COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
    OUTPUT_VARIABLE ARCH_TRIPLET
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

# Set install paths
include(GNUInstallDirs)
set(APPDATA_DIR ${CMAKE_INSTALL_DATADIR}/metainfo)
set(DESKTOP_DIR ${CMAKE_INSTALL_DATADIR}/applications)
set(PLUGINS_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/${APP_NAME})
set(NOSON_GUI "${PLUGINS_DIR}/noson-gui")
set(NOSON_CLI "${PLUGINS_DIR}/noson-cli")

if(NOT QT_STATICPLUGIN)
    set(PLUGINS_BINARY_DIR ${CMAKE_BINARY_DIR}/backend/qml)
    configure_file(
        ${EXEC}.in
        ${CMAKE_CURRENT_BINARY_DIR}/${EXEC}
    )
    install(
        PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${EXEC}"
        DESTINATION ${CMAKE_INSTALL_BINDIR}
    )
else()
    set(PLUGINS_BINARY_DIR "")
endif()

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${APP_DESKTOP_ID}.desktop "[Desktop Entry]
Name=${APP_NAME}
Exec=${EXEC}
Icon=${ICON_NAME}
Terminal=false
Type=Application
Categories=AudioVideo;Audio;")

install(
    FILES ${CMAKE_CURRENT_BINARY_DIR}/${APP_DESKTOP_ID}.desktop
    DESTINATION ${DESKTOP_DIR}
)

install(FILES "gui/icons/${ICON_NAME}-8x8.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/8x8/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-16x16.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/16x16/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-22x22.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/22x22/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-24x24.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/24x24/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-32x32.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/32x32/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-36x36.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/36x36/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-42x42.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/42x42/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-48x48.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/48x48/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-64x64.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/64x64/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-72x72.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/72x72/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-80x80.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/80x80/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-96x96.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/96x96/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-128x128.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/128x128/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-192x192.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/192x192/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-256x256.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/256x256/apps RENAME "${ICON_NAME}.png")
install(FILES "gui/icons/${ICON_NAME}-512x512.png"
    DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/512x512/apps RENAME "${ICON_NAME}.png")

configure_file(
    ${APPDATA_FILE_NAME}.in
    ${CMAKE_CURRENT_BINARY_DIR}/${APPDATA_FILE_NAME}
)

install(
    FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPDATA_FILE_NAME}
    DESTINATION ${APPDATA_DIR} RENAME ${APP_ID}.appdata.xml
)

if(MSVC)
    include(MSVCRuntime)
    set(MSVC_RUNTIME "dynamic")
    configure_msvc_runtime()
endif()

add_subdirectory(backend)

find_package(Qt${QT_VERSION_MAJOR} ${QT_VERSION} COMPONENTS
    Core Gui Qml Quick QuickControls2 Widgets Xml Svg REQUIRED)
if(QT_VERSION VERSION_GREATER_EQUAL 6)
    find_package(Qt6 ${QT_VERSION} COMPONENTS Core5Compat REQUIRED)
endif()
if(ANDROID)
    if(QT_VERSION_MAJOR EQUAL 5)
        find_package(Qt5AndroidExtras REQUIRED)
    endif()
endif()

# Automatically create moc files
set(CMAKE_AUTOMOC ON)

if (QT_VERSION VERSION_LESS 5.99.0)
    qt_add_resources(noson-gui-resources gui/noson_controls2_515.qrc)
elseif (QT_VERSION VERSION_LESS 6.99.0)
    qt_add_resources(noson-gui-resources gui/noson_controls2_640.qrc)
else()
    message(FATAL_ERROR "Qt version is not supported")
endif()

set(
    noson-gui_SOURCES
    src/noson.cpp
    src/diskcache/diskcachefactory.cpp
    src/diskcache/cachingnetworkaccessmanager.cpp
    src/diskcache/cachereply.cpp
)

set(
    noson-gui_HEADERS
    src/diskcache/diskcachefactory.h
    src/diskcache/cachingnetworkaccessmanager.h
    src/diskcache/cachereply.h
)

if(UNIX)
    set(noson-gui_SOURCES ${noson-gui_SOURCES} src/signalhandler.cpp)
    set(noson-gui_HEADERS ${noson-gui_HEADERS} src/signalhandler.h)
endif()

add_definitions(-DAPP_VERSION="${APP_VERSION}")

if(ANDROID)
    add_definitions(-frtti) # dynamic_cast: https://github.com/android/ndk/issues/519
    add_library(noson-gui SHARED ${noson-gui_SOURCES} ${noson-gui_HEADERS} ${noson-gui-resources})
    # Provides dependency openssl
    if(NOT ANDROID_SDK_ROOT)
        set(ANDROID_SDK_ROOT "$ENV{ANDROID_SDK_ROOT}")
        if(NOT ANDROID_SDK_ROOT)
            message(FATAL_ERROR "The ANDROID_SDK_ROOT environment variable is not set")
        endif()
    endif()
    include(${ANDROID_SDK_ROOT}/android_openssl/android_openssl.cmake)
    add_android_openssl_libraries(noson-gui)
    get_target_property(ANDROID_EXTRA_LIBS noson-gui QT_ANDROID_EXTRA_LIBS)
 elseif(MSVC)
    set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /W3 /Od /RTC1")
    set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2 /EHsc /nologo")
    set (CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /O2 /EHsc /nologo")
    set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /O2 /EHsc /nologo")
    set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W3 /Od /RTC1 /EHsc /nologo")
    add_executable(noson-gui WIN32 ${noson-gui_SOURCES} ${noson-gui_HEADERS} ${noson-gui-resources})
else()
    add_executable(noson-gui ${noson-gui_SOURCES} ${noson-gui_HEADERS} ${noson-gui-resources})
endif()

# Link GUI executable
target_link_libraries(noson-gui
    Qt${QT_VERSION_MAJOR}::Gui
    Qt${QT_VERSION_MAJOR}::Qml
    Qt${QT_VERSION_MAJOR}::Quick
    Qt${QT_VERSION_MAJOR}::QuickControls2
    Qt${QT_VERSION_MAJOR}::Widgets
    Qt${QT_VERSION_MAJOR}::Xml
    Qt${QT_VERSION_MAJOR}::Svg)
if(ANDROID)
    if(QT_VERSION_MAJOR EQUAL 5)
        target_link_libraries(noson-gui android log Qt5::AndroidExtras)
    elseif(QT_VERSION_MAJOR EQUAL 6)
        add_definitions(-frtti) # dynamic_cast: https://github.com/android/ndk/issues/519
        set_property(TARGET noson-gui PROPERTY SUFFIX "_${ANDROID_ABI}.so")
        target_link_libraries(noson-gui android log Qt6::CorePrivate)
    endif()
elseif(MSVC)
    target_link_libraries(noson-gui ws2_32)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
    find_library(SOCKET socket REQUIRED)
    find_library(NSL nsl REQUIRED)
    target_link_libraries(noson-gui socket nsl)
endif()

if(QT_STATICPLUGIN)
    add_definitions(-DQT_STATICPLUGIN)
    target_link_libraries(noson-gui NosonApp NosonThumbnailer NosonMediaScanner)
endif()

# Install GUI executable
if(QT_STATICPLUGIN)
    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/noson-gui
            DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME ${EXEC})
else()
    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/noson-gui
            DESTINATION ${PLUGINS_DIR})
endif()

if(ANDROID)
    include(android/AddQtAndroidApk.cmake)
    add_dependencies(noson-gui NosonApp NosonApp-qmldir
        NosonThumbnailer NosonThumbnailer-qmldir
        NosonMediaScanner NosonMediaScanner-qmldir
    )
    add_qt_android_apk(noson-apk noson-gui
        NAME ${APP_NAME}
        VERSION_CODE ${APP_VERSION_CODE}
        PACKAGE_NAME ${APP_ID}
        PACKAGE_SOURCES ${PROJECT_SOURCE_DIR}/android/package-sources
        DEPENDS FLAC FLACXX ${ANDROID_EXTRA_LIBS}
        PLUGINS platforms tls iconengines imageformats networkinformation
                qmltooling styles
        KEYSTORE ${KEYSTORE_FILE} ${KEYSTORE_ALIAS}
        KEYSTORE_PASSWORD ${KEYSTORE_PASSWORD}
    )
endif()

# Add custom target uninstall
configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY
)

add_custom_target(
    "uninstall"
    ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
)

# Add custom target run with debug
if(QT_STATICPLUGIN)
    add_custom_target(
        "run"
        ${CMAKE_BINARY_DIR}/${EXEC} --debug
        DEPENDS noson-gui
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    )
else()
    add_custom_target(
        "run"
        QML2_IMPORT_PATH=${PLUGINS_BINARY_DIR} ${CMAKE_BINARY_DIR}/noson-gui --debug
        DEPENDS noson-gui
                NosonApp NosonApp-qmldir
                NosonThumbnailer NosonThumbnailer-qmldir
                NosonMediaScanner NosonMediaScanner-qmldir
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    )
endif()

feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES)
