cmake_minimum_required(VERSION 3.25)

file(READ "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg.json" _pdfengine_vcpkg_json)
string(JSON _pdfengine_baseline ERROR_VARIABLE _pdfengine_baseline_err
       GET "${_pdfengine_vcpkg_json}" "builtin-baseline")
if(_pdfengine_baseline_err OR NOT _pdfengine_baseline)
    message(FATAL_ERROR
        "vcpkg.json has no 'builtin-baseline' — the dependency registry is not "
        "pinned.\n"
        "Run the bootstrap script first:\n"
        "    Windows:  pwsh scripts/bootstrap.ps1\n"
        "    Unix:     ./scripts/bootstrap.sh\n"
        "It installs vcpkg and runs 'vcpkg x-update-baseline --add-initial-baseline'.")
endif()

project(PdfEngine
    VERSION 0.1.0
    DESCRIPTION "Cross-platform PDF rendering and editing SDK"
    HOMEPAGE_URL "https://example.invalid/pdf-engine"
    LANGUAGES CXX)

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

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

if(EMSCRIPTEN)
    set(PDFENGINE_WASM ON CACHE INTERNAL "Building for WebAssembly")
endif()

option(PDFENGINE_BUILD_TESTS      "Build engine unit/smoke tests"                ON)
option(PDFENGINE_ENABLE_SANITIZERS "Build with AddressSanitizer/UBSan"           OFF)
option(PDFENGINE_WARNINGS_AS_ERRORS "Treat compiler warnings as errors"          OFF)
option(PDFENGINE_WITH_PDFIUM      "Link the PDFium static lib (build it first)"  OFF)
option(PDFENGINE_WITH_SKIA        "Link the Skia static lib (build it first)"    OFF)
option(PDFENGINE_WITH_QPDF        "Link QPDF for content stream extraction"      OFF)
option(PDFENGINE_FUZZING          "Build libFuzzer harnesses (requires Clang)"   OFF)

if(PDFENGINE_FUZZING)
    # The fuzz harness instruments the engine; tests/bindings are not part of it.
    set(PDFENGINE_BUILD_TESTS OFF CACHE BOOL "Build engine unit/smoke tests" FORCE)
    if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        message(FATAL_ERROR "PDFENGINE_FUZZING requires a Clang/clang-cl toolchain "
                            "(set in the 'fuzz-*' preset).")
    endif()
endif()

if(PDFENGINE_WASM)
    set(PDFENGINE_BUILD_TESTS OFF CACHE BOOL "Build engine unit/smoke tests" FORCE)
    set(PDFENGINE_ENABLE_SANITIZERS OFF CACHE BOOL "ASan/UBSan" FORCE)
    # PDFium under WASM is opt-in via the wasm-pdfium preset (links the prebuilt wasm32
    # libpdfium.a). The plain 'wasm' preset leaves PDFENGINE_WITH_PDFIUM=OFF (mock engine).
endif()

include(CompilerWarnings)
include(Sanitizers)

if(PDFENGINE_WITH_PDFIUM)
    include(pdfium)        # defines pdfium::pdfium when PDFENGINE_WITH_PDFIUM is ON
endif()
if(PDFENGINE_WITH_SKIA)
    include(skia)          # defines skia::skia when PDFENGINE_WITH_SKIA is ON
endif()

find_package(freetype  CONFIG REQUIRED)
find_package(harfbuzz  CONFIG REQUIRED)
find_package(spdlog    CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
if(PDFENGINE_WITH_QPDF)
    find_package(qpdf      CONFIG REQUIRED)
endif()
if(WIN32 AND DEFINED VCPKG_TARGET_TRIPLET)
    link_directories("${CMAKE_BINARY_DIR}/vcpkg_installed/${VCPKG_TARGET_TRIPLET}/lib")
    link_directories("${CMAKE_BINARY_DIR}/vcpkg_installed/${VCPKG_TARGET_TRIPLET}/debug/lib")
endif()

if(PDFENGINE_BUILD_TESTS)
    find_package(GTest CONFIG REQUIRED)
    enable_testing()
    include(GoogleTest)
endif()

if(PDFENGINE_WASM)
    message(STATUS "PdfEngine ${PROJECT_VERSION} — WASM configuration (Phase 1/2 Enabled)")
    add_subdirectory(engine)
    add_subdirectory(wasm)
else()
    # Only the top-level project drives testing/install defaults.
    if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
        message(FATAL_ERROR "In-source builds are not allowed. Use a preset: "
                            "cmake --preset <platform>-debug")
    endif()

    add_subdirectory(engine)
    if(NOT PDFENGINE_FUZZING)
        add_subdirectory(bindings)
    endif()
endif()

message(STATUS "PdfEngine ${PROJECT_VERSION} configured")
message(STATUS "  C++ standard ......... ${CMAKE_CXX_STANDARD}")
message(STATUS "  Build tests .......... ${PDFENGINE_BUILD_TESTS}")
message(STATUS "  Sanitizers ........... ${PDFENGINE_ENABLE_SANITIZERS}")
message(STATUS "  Warnings as errors ... ${PDFENGINE_WARNINGS_AS_ERRORS}")
message(STATUS "  Link PDFium .......... ${PDFENGINE_WITH_PDFIUM}")
message(STATUS "  Link Skia ............ ${PDFENGINE_WITH_SKIA}")