cmake_minimum_required(VERSION 3.24)
project(MizinPlayout LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt6 6.8 REQUIRED COMPONENTS Widgets Multimedia MultimediaWidgets Concurrent OpenGL OpenGLWidgets Network)
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../evidence/build-version.json")
  message(FATAL_ERROR "Use scripts/build.ps1 to generate the version from target commits first.")
endif()
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/../evidence/build-version.json" VERSION_JSON)
string(JSON MIZIN_VERSION GET "${VERSION_JSON}" display)
string(JSON MIZIN_SOURCE_COMMIT GET "${VERSION_JSON}" source_commit)
configure_file(src/version.hpp.in generated/version.hpp @ONLY)
qt_add_executable(MizinPlayout src/main.cpp src/channel.cpp src/channel.hpp src/cue.hpp src/compositor.hpp src/playlist.hpp src/smoke.cpp src/smoke.hpp src/transport_tests.cpp src/scaler.hpp src/scaler.cpp src/output.hpp src/output.cpp src/output_tests.cpp src/gpu_scaler.hpp src/gpu_scaler.cpp src/gpu_tests.cpp src/audio.hpp src/audio.cpp src/network_runtime.hpp src/network_runtime.cpp src/network.hpp src/network.cpp src/routing_panels.hpp src/routing_panels.cpp src/network_tests.cpp src/readiness.hpp src/readiness_tests.cpp src/diagnostics_panel.hpp src/diagnostics_panel.cpp)
target_include_directories(MizinPlayout PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/generated" "${CMAKE_CURRENT_SOURCE_DIR}/third_party/ndi" "${CMAKE_CURRENT_SOURCE_DIR}/third_party/omt")
target_link_libraries(MizinPlayout PRIVATE Qt6::Widgets Qt6::Multimedia Qt6::MultimediaWidgets Qt6::Concurrent Qt6::OpenGL Qt6::OpenGLWidgets)
target_sources(MizinPlayout PRIVATE src/process_usage.cpp src/process_usage.hpp src/updates.cpp src/updates.hpp src/update_tests.cpp)
target_link_libraries(MizinPlayout PRIVATE Qt6::Network)
# ADR-017 local WebRTC monitor: libdatachannel (MPL-2.0, Mbed TLS inside datachannel.dll) and Opus,
# built from pinned sources by scripts/build-web-sdk.cmd. H.264 uses the Windows Media Foundation encoder.
set(MIZIN_WEB_SDK "${CMAKE_CURRENT_SOURCE_DIR}/../binaries/web-sdk/install" CACHE PATH "WebRTC monitor dependencies")
if(NOT EXISTS "${MIZIN_WEB_SDK}/lib/datachannel.lib" OR NOT EXISTS "${MIZIN_WEB_SDK}/lib/opus.lib")
  message(FATAL_ERROR "Run scripts/build-web-sdk.cmd first (ADR-017).")
endif()
target_sources(MizinPlayout PRIVATE src/web_encoder.hpp src/web_encoder.cpp src/web_monitor.hpp src/web_monitor.cpp src/web_tests.cpp)
target_include_directories(MizinPlayout PRIVATE "${MIZIN_WEB_SDK}/include" "${MIZIN_WEB_SDK}/include/opus")
target_link_libraries(MizinPlayout PRIVATE "${MIZIN_WEB_SDK}/lib/datachannel.lib" "${MIZIN_WEB_SDK}/lib/opus.lib")
if(WIN32)
  target_link_libraries(MizinPlayout PRIVATE mfplat mfuuid wmcodecdspuuid strmiids ole32)
endif()
# ADR-018 low-latency local audio (WASAPI always; ASIO only with the Steinberg SDK and its licence).
target_sources(MizinPlayout PRIVATE src/local_audio.hpp src/local_audio.cpp src/local_audio_asio.cpp src/local_audio_tests.cpp)
# ADR-019 Mizin Link (multi-machine).
target_sources(MizinPlayout PRIVATE src/link.hpp src/link.cpp src/link_tests.cpp)
if(WIN32)
  target_link_libraries(MizinPlayout PRIVATE avrt)
endif()
option(MIZIN_ENABLE_ASIO "Build the ASIO backend. A Steinberg-signed licence agreement is required before publishing such a build." OFF)
if(MIZIN_ENABLE_ASIO)
  set(MIZIN_ASIO_SDK "${CMAKE_CURRENT_SOURCE_DIR}/../binaries/asio-sdk/src/ASIOSDK" CACHE PATH "Steinberg ASIO SDK")
  if(NOT EXISTS "${MIZIN_ASIO_SDK}/common/asio.h")
    message(FATAL_ERROR "ASIO SDK not found at ${MIZIN_ASIO_SDK}")
  endif()
  # The SDK host code uses ANSI Win32 APIs: build it apart from the Unicode Qt target.
  add_library(mizin_asio STATIC "${MIZIN_ASIO_SDK}/common/asio.cpp" "${MIZIN_ASIO_SDK}/host/asiodrivers.cpp" "${MIZIN_ASIO_SDK}/host/pc/asiolist.cpp")
  target_include_directories(mizin_asio PUBLIC "${MIZIN_ASIO_SDK}/common" "${MIZIN_ASIO_SDK}/host" "${MIZIN_ASIO_SDK}/host/pc")
  target_compile_options(mizin_asio PRIVATE /W0)
  target_link_libraries(mizin_asio PUBLIC ole32 advapi32)
  target_link_libraries(MizinPlayout PRIVATE mizin_asio)
  target_compile_definitions(MizinPlayout PRIVATE MIZIN_ENABLE_ASIO)
endif()
if(WIN32)
  enable_language(RC)
  string(REGEX MATCH "v([0-9]+)[.]([0-9]+)[.]([0-9]+) \\(build ([0-9]+)\\)" VERSION_MATCH "${MIZIN_VERSION}")
  set(MIZIN_VERSION_PARTS "${CMAKE_MATCH_1},${CMAKE_MATCH_2},${CMAKE_MATCH_3}")
  string(REGEX REPLACE "^0+" "" MIZIN_BUILD_NUMBER "${CMAKE_MATCH_4}")
  if(MIZIN_BUILD_NUMBER STREQUAL "")
    set(MIZIN_BUILD_NUMBER 0)
  endif()
  set(MIZIN_VERSION_NUMERIC "${MIZIN_VERSION_PARTS},${MIZIN_BUILD_NUMBER}")
  configure_file(src/windows.rc.in generated/windows.rc @ONLY)
  configure_file(src/update_helper.rc.in generated/update_helper.rc @ONLY)
  add_executable(MizinUpdater WIN32 src/update_helper.cpp "${CMAKE_CURRENT_BINARY_DIR}/generated/update_helper.rc")
  set_property(TARGET MizinUpdater PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
  set_property(TARGET MizinUpdater PROPERTY AUTOMOC OFF)
  target_compile_definitions(MizinUpdater PRIVATE UNICODE _UNICODE)
  target_compile_options(MizinUpdater PRIVATE /utf-8 /W4)
  target_link_libraries(MizinUpdater PRIVATE bcrypt shell32 user32 gdi32)
  target_sources(MizinPlayout PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/generated/windows.rc")
  target_link_libraries(MizinPlayout PRIVATE pdh psapi dxgi bcrypt)
endif()
if(MSVC)
  target_compile_options(MizinPlayout PRIVATE /utf-8 /W4)
  target_link_options(MizinPlayout PRIVATE /NODEFAULTLIB:libomt.lib)
endif()
set_target_properties(MizinPlayout PROPERTIES WIN32_EXECUTABLE TRUE)
qt_add_resources(MizinPlayout "product" PREFIX "/" FILES i18n/en.json i18n/pt-BR.json web/monitor.html)
