#/***************************************************************************
# *   Copyright (C) 2026 by l4rzy <me@23ro.org>                            *
# *                                                                         *
# *   This program is free software; you can redistribute it and/or modify  *
# *   it under the terms of the GNU General Public License as published by  *
# *   the Free Software Foundation; either version 3 of the License, or     *
# *   (at your option) any later version.                                   *
# ***************************************************************************/

cmake_minimum_required(VERSION 3.20.0)
project(okular-mupdf-ng)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

option(BUILD_OKULAR_GENERATOR "Build the Okular generator and KDE integration" ON)
option(ENABLE_SANITIZERS "Enable Address/LeakSanitizer instrumentation" OFF)
option(ENABLE_LTO "Enable supported LTO in optimized CMake configurations" ON)
option(DISABLE_WORKER_SANDBOX "Disable worker sandboxing for diagnostic builds" OFF)
add_compile_definitions(MU_DISABLE_WORKER_SANDBOX=$<BOOL:${DISABLE_WORKER_SANDBOX}>)
find_package(PkgConfig REQUIRED)
include(FeatureSummary)
if(BUILD_OKULAR_GENERATOR)
    find_package(ECM 6.3.0 CONFIG REQUIRED)
    list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
    include(KDEInstallDirs)
    if(ENABLE_SANITIZERS)
        set(ECM_ENABLE_SANITIZERS "address;leak" CACHE STRING
            "ECM sanitizer set for the release test build" FORCE)
    endif()
    include(ECMEnableSanitizers)
    include(KDECMakeSettings)
else()
    include(GNUInstallDirs)
    set(CMAKE_AUTOMOC ON)
    if(ENABLE_SANITIZERS)
        add_compile_options(-fsanitize=address -fno-omit-frame-pointer)
        add_link_options(-fsanitize=address)
    endif()
endif()
include(CTest)

# Keep Debug/sanitizer builds and packaging's None configuration under their
# existing flag policy. IPO applies to CMake targets, not MuPDF's external Make build.
set(MU_LTO_ENABLED OFF)
if(ENABLE_LTO AND NOT ENABLE_SANITIZERS AND
   (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE MATCHES "^(Release|RelWithDebInfo|MinSizeRel)$"))
    include(CheckIPOSupported)
    if(POLICY CMP0138)
        cmake_policy(SET CMP0138 NEW)
    endif()
    check_ipo_supported(RESULT MU_LTO_SUPPORTED OUTPUT MU_LTO_ERROR LANGUAGES C CXX)
    if(MU_LTO_SUPPORTED)
        foreach(config RELEASE RELWITHDEBINFO MINSIZEREL)
            set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_${config} ON)
        endforeach()
        set(MU_LTO_ENABLED ON)
    else()
        message(WARNING "LTO unavailable; continuing without it: ${MU_LTO_ERROR}")
    endif()
endif()

# Only the exact Debug configuration defaults to verbose diagnostics. None is used
# by Arch packaging so that makepkg owns the compiler flags; it must still
# produce a release-profile MuPDF build. The bundled MuPDF profile itself is
# controlled by MUPDF_OPTIMIZED_BUILD (default ON: release profile in every
# preset).
set(MU_IS_DEBUG_BUILD OFF)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    set(MU_IS_DEBUG_BUILD ON)
endif()

# CJK fallback policy for the bundled MuPDF engine. Source Han Serif has the
# best fidelity (~24 MiB) while the Droid fonts trade per-locale coverage for a
# much smaller worker. Ignored when USE_SYSTEM_MUPDF=ON, since the system
# library decides its own embedded fonts. Changing this in an existing build
# directory requires removing build/mupdf/<profile> so the archives rebuild.
set(MUPDF_CJK_FALLBACK "droidfull" CACHE STRING
    "Bundled MuPDF CJK fallback: sourcehan | droidfull | droid | none")
set_property(CACHE MUPDF_CJK_FALLBACK PROPERTY STRINGS sourcehan droidfull droid none)
string(TOLOWER "${MUPDF_CJK_FALLBACK}" _mupdf_cjk_fallback)
if(NOT _mupdf_cjk_fallback MATCHES "^(sourcehan|droidfull|droid|none)$")
    message(FATAL_ERROR
        "Invalid MUPDF_CJK_FALLBACK='${MUPDF_CJK_FALLBACK}' (expected sourcehan | droidfull | droid | none)")
endif()

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/mupdf.cmake")

set(TESSDATA_DIR "/usr/share/tessdata" CACHE PATH "Path to tesseract tessdata directory")
set(SIGNATURE_FONT_DIR "${CMAKE_INSTALL_FULL_DATADIR}/okular-mupdf-ng" CACHE PATH
    "Directory containing the bundled signature font")

find_package(Threads REQUIRED)
find_package(ZLIB REQUIRED)
pkg_check_modules(NSS REQUIRED nss)
pkg_check_modules(SECCOMP QUIET libseccomp)
find_package(Qt6 REQUIRED COMPONENTS Core Gui)
if(BUILD_OKULAR_GENERATOR)
    find_package(Okular6 REQUIRED)
    find_package(KF6 REQUIRED COMPONENTS CoreAddons I18n Config ConfigWidgets KIO XmlGui WidgetsAddons)
    find_package(Qt6 REQUIRED COMPONENTS Concurrent PrintSupport Network Xml)
endif()

option(ENABLE_BUILD_TREE_WORKER
    "Embed the build-tree worker for uninstalled developer runs"
    ${MU_IS_DEBUG_BUILD})

option(ENABLE_MU_DEBUG "Compile verbose Mu diagnostics" ${MU_IS_DEBUG_BUILD})
set(MU_DEBUG_BUILD OFF)
if(ENABLE_MU_DEBUG)
    set(MU_DEBUG_BUILD ON)
endif()

file(READ "${CMAKE_CURRENT_SOURCE_DIR}/src/generator/manifest.json" MU_GENERATOR_MANIFEST)
string(JSON MU_COMPAT_VERSION ERROR_VARIABLE MU_MANIFEST_ERROR
    GET "${MU_GENERATOR_MANIFEST}" KPlugin Version)
if(MU_MANIFEST_ERROR)
    message(FATAL_ERROR "Cannot read KPlugin.Version from the generator manifest: ${MU_MANIFEST_ERROR}")
endif()
if(NOT MU_COMPAT_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+$")
    message(FATAL_ERROR "KPlugin.Version must use MAJOR.MINOR.PATCH: ${MU_COMPAT_VERSION}")
endif()
set(MU_GENERATED_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
configure_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/src/shared/compat.hpp.in"
    "${MU_GENERATED_INCLUDE_DIR}/shared/compat.hpp"
    @ONLY)

set(MUPDF_WORKER_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/okular-mupdf-ng")
set(WORKER_INSTALL_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/okular-mupdf-ng/mupdfng-worker"
    CACHE PATH "Installed path of the mupdfng-worker binary")
add_subdirectory(src)

if(BUILD_OKULAR_GENERATOR)
    install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/dist/mupdfng.svg"
        DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps")
endif()
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/COPYING"
    DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/okular-mupdf-ng"
    RENAME copyright)
install(FILES
    "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/allura/Allura-Regular.ttf"
    DESTINATION "${SIGNATURE_FONT_DIR}")
install(FILES
    "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/allura/OFL.txt"
    DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/okular-mupdf-ng"
    RENAME Allura-OFL.txt)
# MuPDF is AGPL-3.0-or-later; ship its license text alongside the plugin. Only
# MuPDF's own license is redistributed here, not its bundled sub-dependencies.
install(FILES
    "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/mupdf-COPYING"
    DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/okular-mupdf-ng"
    RENAME MuPDF-COPYING)

message(STATUS "Manifest version: ${MU_COMPAT_VERSION}")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "LTO for optimized configurations: ${MU_LTO_ENABLED}")
message(STATUS "MuPDF build profile: ${MUPDF_BUILD_PROFILE}")
message(STATUS "MuPDF CJK fallback: ${MUPDF_CJK_FALLBACK}")
message(STATUS "PDF form JavaScript: ${ENABLE_FORM_JAVASCRIPT}")
message(STATUS "Mu debug diagnostics: ${MU_DEBUG_BUILD}")
message(STATUS "Worker install path: ${WORKER_INSTALL_PATH}")
message(STATUS "Build-tree worker: ${ENABLE_BUILD_TREE_WORKER}")
message(STATUS "Tessdata directory: ${TESSDATA_DIR}")
message(STATUS "Signature font directory: ${SIGNATURE_FONT_DIR}")
message(STATUS "Seccomp support: ${SECCOMP_FOUND}")
# Both build profiles expose the standard BUILD_TESTING option.
if(BUILD_TESTING)
    add_subdirectory(tests)
endif()

if(BUILD_OKULAR_GENERATOR AND IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po")
    ki18n_install(po)
endif()

feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)

set(CPACK_PACKAGE_NAME "okular-mupdf-ng")
set(CPACK_PACKAGE_VERSION "${MU_COMPAT_VERSION}")
set(CPACK_PACKAGE_CONTACT "l4rzy <me@23ro.org>")
if(BUILD_OKULAR_GENERATOR)
    set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A MuPDF-based secure and fast backend for Okular")
    set(MU_APPLICATION_PACKAGE_DEPENDS "okular")
else()
    set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Command-line PDF and ePUB tools using a sandboxed MuPDF worker")
    set(MU_APPLICATION_PACKAGE_DEPENDS "")
endif()
set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/l4rzy/okular-mupdf-ng")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
set(CPACK_DEBIAN_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")
set(CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}")
set(CPACK_DEBIAN_PACKAGE_RELEASE 1)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_CONTACT}")
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${MU_APPLICATION_PACKAGE_DEPENDS}")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_RPM_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")
set(CPACK_RPM_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}")
set(CPACK_RPM_PACKAGE_RELEASE 1)
set(CPACK_RPM_PACKAGE_LICENSE "GPL-3.0-or-later")
set(CPACK_RPM_PACKAGE_GROUP "Productivity/Office/Other")
set(CPACK_RPM_PACKAGE_VENDOR "l4rzy")
set(CPACK_RPM_PACKAGE_URL "${CPACK_PACKAGE_HOMEPAGE_URL}")
set(CPACK_RPM_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
set(CPACK_RPM_PACKAGE_REQUIRES
    "${MU_APPLICATION_PACKAGE_DEPENDS}"
    CACHE STRING "Explicit runtime dependencies for RPM packages")
set(CPACK_RPM_FILE_NAME RPM-DEFAULT)
include(CPack)
