cmake_minimum_required(VERSION 3.22)
project(DCPPlayer VERSION 1.1.0 LANGUAGES CXX)
find_package(EXPAT REQUIRED)
find_package(Threads REQUIRED)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(ThirdParty/ASDCP.cmake)

add_library(dcp_dcp_core
    Sources/Core/AudioRouting.cpp
    Sources/Core/ColorPipeline.cpp
    Sources/Core/OutputRegistry.cpp
    Sources/Core/DCPPackage.cpp
    Sources/Core/Subtitles.cpp
    Sources/Core/PlaybackPlan.cpp
)
target_include_directories(dcp_dcp_core PUBLIC Sources)
target_link_libraries(dcp_dcp_core PUBLIC EXPAT::EXPAT dcp_asdcp)

add_executable(core_tests Tests/CoreTests.cpp)
target_link_libraries(core_tests PRIVATE dcp_dcp_core)
enable_testing()
add_test(NAME core_tests COMMAND core_tests)
add_executable(package_tests Tests/PackageTests.cpp)
target_link_libraries(package_tests PRIVATE dcp_dcp_core)
add_test(NAME package_tests COMMAND package_tests)
add_executable(audio_naming_tests Tests/AudioNamingTests.cpp)
target_link_libraries(audio_naming_tests PRIVATE dcp_dcp_core)
target_compile_options(audio_naming_tests PRIVATE -UNDEBUG)
add_test(NAME audio_naming_tests COMMAND audio_naming_tests)
add_executable(playback_tests Tests/PlaybackTests.cpp)
target_link_libraries(playback_tests PRIVATE dcp_dcp_core Threads::Threads)
add_test(NAME playback_tests COMMAND playback_tests)

add_executable(rgb_tests Tests/RGBTests.cpp)
target_link_libraries(rgb_tests PRIVATE dcp_dcp_core)
add_test(NAME rgb_tests COMMAND rgb_tests)

add_executable(audio_planar_tests Tests/AudioPlanarTests.cpp)
target_link_libraries(audio_planar_tests PRIVATE dcp_dcp_core)
add_test(NAME audio_planar_tests COMMAND audio_planar_tests)

add_executable(kdm_payload_tests Tests/KDMPayloadTests.cpp)
target_link_libraries(kdm_payload_tests PRIVATE dcp_dcp_core)
add_test(NAME kdm_payload_tests COMMAND kdm_payload_tests)

add_executable(subtitle_tests Tests/SubtitleTests.cpp)
target_link_libraries(subtitle_tests PRIVATE dcp_dcp_core)
add_test(NAME subtitle_tests COMMAND subtitle_tests)
add_executable(mxf_decrypt_tests Tests/MXFDecryptTests.cpp)
target_link_libraries(mxf_decrypt_tests PRIVATE dcp_asdcp)
add_test(NAME mxf_decrypt_tests COMMAND mxf_decrypt_tests $<TARGET_FILE:mxf_decrypt>)
add_executable(mxf_decrypt Sources/Tools/MXFDecrypt.cpp)
target_link_libraries(mxf_decrypt PRIVATE dcp_asdcp)

find_package(Python3 COMPONENTS Interpreter QUIET)
if(Python3_Interpreter_FOUND)
  add_test(NAME kdm_crypto_tests COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Tests/KDMCryptoTests.py)
  set_tests_properties(kdm_crypto_tests PROPERTIES SKIP_RETURN_CODE 77 TIMEOUT 30)
endif()

if(APPLE)
  enable_language(OBJCXX)
  set(AJANTV2_DISABLE_DEMOS ON CACHE BOOL "" FORCE)
  set(AJANTV2_DISABLE_TOOLS ON CACHE BOOL "" FORCE)
  set(AJANTV2_DISABLE_TESTS ON CACHE BOOL "" FORCE)
  set(AJANTV2_DISABLE_DRIVER ON CACHE BOOL "" FORCE)
  set(AJANTV2_DISABLE_PLUGIN_LOAD ON CACHE BOOL "" FORCE)
  set(AJANTV2_BUILD_SHARED OFF CACHE BOOL "" FORCE)
  set(AJANTV2_BUILD_FRAMEWORK OFF CACHE BOOL "" FORCE)
  set(AJA_INSTALL_CMAKE OFF CACHE BOOL "" FORCE)
  add_subdirectory(ThirdParty/libajantv2 EXCLUDE_FROM_ALL)
  enable_language(OBJCXX)
  set(CMAKE_OBJCXX_STANDARD 20)
  set(CMAKE_OBJCXX_STANDARD_REQUIRED ON)
  add_executable(subtitle_metal_tests Tests/SubtitleMetalTests.mm)
  target_compile_options(subtitle_metal_tests PRIVATE -fobjc-arc)
  target_link_libraries(subtitle_metal_tests PRIVATE "-framework Foundation" "-framework Metal")
  add_test(NAME subtitle_metal_tests COMMAND subtitle_metal_tests "${CMAKE_CURRENT_SOURCE_DIR}/Resources/SubtitleShaders.metal")
  set_tests_properties(subtitle_metal_tests PROPERTIES SKIP_RETURN_CODE 77)
  add_executable(metal_tests Tests/MetalTests.mm)
  target_compile_options(metal_tests PRIVATE -fobjc-arc)
  target_link_libraries(metal_tests PRIVATE dcp_dcp_core "-framework Foundation" "-framework Metal")
  add_test(NAME metal_tests COMMAND metal_tests "${CMAKE_CURRENT_SOURCE_DIR}/Resources/PlayerShaders.metal")
  set_tests_properties(metal_tests PROPERTIES SKIP_RETURN_CODE 77)
  add_executable(sdi_metal_tests Tests/SDIMetalTests.mm)
  target_compile_options(sdi_metal_tests PRIVATE -fobjc-arc)
  target_link_libraries(sdi_metal_tests PRIVATE dcp_dcp_core "-framework Foundation" "-framework Metal")
  add_test(NAME sdi_metal_tests COMMAND sdi_metal_tests "${CMAKE_CURRENT_SOURCE_DIR}/Resources/SDIShaders.metal")
  set_tests_properties(sdi_metal_tests PROPERTIES SKIP_RETURN_CODE 77)
  add_executable(DCPPlayer MACOSX_BUNDLE
      Sources/macOS/main.mm
      Sources/macOS/CoreAudioDevices.mm
      Sources/macOS/PackageWindow.mm
      Sources/macOS/MetadataInspector.mm
      Sources/macOS/PlaybackEngine.mm
      Sources/macOS/MetalCanvas.mm
      Sources/macOS/SubtitleCompositor.mm
      Sources/macOS/AudioMeters.mm
      Sources/macOS/KDMManager.mm
      Sources/macOS/ExternalOutput.mm
      Sources/macOS/BlackmagicVideo.mm
      Sources/macOS/AJAVideo.cpp
      ThirdParty/DeckLink/include/DeckLinkAPIDispatch.cpp
      Resources/CertificateIdentity.py
      Resources/AppIcon.icns
      Resources/PlayerShaders.metal
  )
  set_source_files_properties(Resources/CertificateIdentity.py PROPERTIES MACOSX_PACKAGE_LOCATION Resources HEADER_FILE_ONLY TRUE)
  set_source_files_properties(Resources/AppIcon.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
  set_source_files_properties(Resources/PlayerShaders.metal PROPERTIES MACOSX_PACKAGE_LOCATION Resources HEADER_FILE_ONLY TRUE)
  target_compile_options(DCPPlayer PRIVATE "$<$<COMPILE_LANGUAGE:OBJCXX>:-fobjc-arc>")
  target_include_directories(DCPPlayer PRIVATE ThirdParty/DeckLink/include)
  target_link_libraries(DCPPlayer PRIVATE ajantv2 "-framework CoreFoundation")
  target_link_libraries(DCPPlayer PRIVATE dcp_dcp_core
      "-framework AppKit" "-framework CoreAudio" "-framework AudioToolbox" "-framework AudioUnit" "-framework Metal" "-framework MetalKit" "-framework QuartzCore" "-framework CoreText")
  set_target_properties(DCPPlayer PROPERTIES
      OUTPUT_NAME "DCP Player"
      XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.joaofariapost.dcpplayer"
      MACOSX_BUNDLE_SHORT_VERSION_STRING "1.1.0"
      MACOSX_BUNDLE_BUNDLE_VERSION "110"
      MACOSX_BUNDLE_ICON_FILE "AppIcon.icns"
      XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES"
      MACOSX_BUNDLE_GUI_IDENTIFIER "com.joaofariapost.dcpplayer"
      MACOSX_BUNDLE_BUNDLE_NAME "DCP Player"
  )
  add_custom_command(TARGET DCPPlayer POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
    "${CMAKE_CURRENT_SOURCE_DIR}/Resources/PlayerShaders.metal"
    "$<TARGET_BUNDLE_DIR:DCPPlayer>/Contents/Resources/PlayerShaders.metal")
  add_custom_command(TARGET DCPPlayer POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/Resources/SDIShaders.metal"
    "$<TARGET_BUNDLE_DIR:DCPPlayer>/Contents/Resources/SDIShaders.metal")
  add_custom_command(TARGET DCPPlayer POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/Resources/SubtitleShaders.metal"
    "$<TARGET_BUNDLE_DIR:DCPPlayer>/Contents/Resources/SubtitleShaders.metal")
  add_custom_command(TARGET DCPPlayer POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/Resources/Licenses"
    "$<TARGET_BUNDLE_DIR:DCPPlayer>/Contents/Resources/Licenses")
  add_dependencies(DCPPlayer mxf_decrypt)
  add_custom_command(TARGET DCPPlayer POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:mxf_decrypt>"
    "$<TARGET_BUNDLE_DIR:DCPPlayer>/Contents/MacOS/mxf_decrypt")
  add_test(NAME app_smoke COMMAND $<TARGET_FILE:DCPPlayer> --smoke-test)
  set_tests_properties(app_smoke PROPERTIES TIMEOUT 30 RUN_SERIAL TRUE)
endif()
