# ------------------------------
# cmake config / project
# ------------------------------
cmake_minimum_required(VERSION 3.25.0)

set(CMAKE_CXX_STANDARD 20)
if(MSVC)
	set(CMAKE_CXX_FLAGS "/EHsc /D_AMD64_ /DWIN32_LEAN_AND_MEAN")
	set(CMAKE_CXX_FLAGS_RELEASE "/O2 /DNDEBUG")
else()
	set(CMAKE_CXX_FLAGS "-D_AMD64_ -DWIN32_LEAN_AND_MEAN")
	set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
endif()

project(dbd-unlocker LANGUAGES CXX)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
if(CMAKE_GENERATOR MATCHES "Visual Studio")
	enable_language(CSharp)
endif()

# ------------------------------
# msvc stuff
# ------------------------------
if(CMAKE_GENERATOR MATCHES "Visual Studio")
	set(CMAKE_CSharp_PROJECT_TYPE_GUID "9A19103F-16F7-4668-BE54-9A1E7A4F7556")
endif()

if(CMAKE_GENERATOR MATCHES "Visual Studio")
	string(APPEND CMAKE_CXX_FLAGS " /EHsc /DWIN32_LEAN_AND_MEAN /utf-8 /Zc:char8_t")
	if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
		string(APPEND CMAKE_CXX_FLAGS " /D_AMD64_")
	elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "Win32")
		string(APPEND CMAKE_CXX_FLAGS " /D_WIN32_")
	else()
		message(FATAL_ERROR "unhandled architecture")
	endif()
endif()

# ------------------------------------------------------
# folder grouping
# ------------------------------------------------------
function(group_files sources)
	foreach(FILE ${sources})
		get_filename_component(PARENT_DIR "${FILE}" DIRECTORY)
		string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" GROUP "${PARENT_DIR}") # remove full dir
		string(REGEX MATCH "[A-Za-z0-9_-]+/[A-Za-z0-9_-]+" GROUPNAME ${GROUP}) # get the first two folders from dir
		string(LENGTH ${GROUPNAME} GROUPLEN) # get project name len
		string(SUBSTRING ${GROUP} ${GROUPLEN} -1 GROUP) # remove project name from dir
		source_group("${GROUP}" FILES "${FILE}") # group file
	endforeach()
endfunction()

# ---------------------
# dependencies
# ---------------------
find_package(OpenSSL REQUIRED)
add_subdirectory(vendor)

# ---------------------
# warnings
# ---------------------
add_library(dbd-unlocker-warnings INTERFACE)
if(CMAKE_GENERATOR MATCHES "Visual Studio")
	target_compile_options(dbd-unlocker-warnings INTERFACE /W4 /WX)
else()
	target_compile_options(dbd-unlocker-warnings INTERFACE -Wall -Wextra -Werror)
endif()

# ------------------------------
# unlocker
# ------------------------------
file(GLOB_RECURSE UNLOCKER_SOURCES CONFIGURE_DEPENDS "src/unlocker/*.cpp" "src/unlocker/*.h")
add_executable(dbd-unlocker ${UNLOCKER_SOURCES})

# randomize exe name
string(RANDOM LENGTH 12 ALPHABET "abcdefghijklmnopqrstuvwxyz0123456789" RANDOM_EXE_NAME)
set_target_properties(dbd-unlocker PROPERTIES OUTPUT_NAME "${RANDOM_EXE_NAME}")

target_link_libraries(dbd-unlocker PRIVATE dbd-unlocker-warnings OpenSSL::SSL OpenSSL::Crypto nerutils wsock32 ws2_32 wininet crypt32 nlohmann_json zlibstatic )

if(NOT MSVC)
    target_link_options(dbd-unlocker PRIVATE -static -static-libgcc -static-libstdc++)
endif()

set_property(TARGET dbd-unlocker PROPERTY USE_FOLDERS ON)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT dbd-unlocker)

group_files("${UNLOCKER_SOURCES}")

# copy resources
file(GLOB JSON_RES_FILES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/res/*.json")
add_custom_command(TARGET dbd-unlocker POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
        ${JSON_RES_FILES}
        "$<TARGET_FILE_DIR:dbd-unlocker>/"
    COMMENT "copying sources"
)

# ------------------------------
# VS only
# ------------------------------
if(CMAKE_GENERATOR MATCHES "Visual Studio")
	# ------------------------------
	# CUE4Parse
	# ------------------------------
	set(CUE4PARSE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vendor/CUE4Parse")

	# CUE4Parse natives
	set(CUE4PARSE_NATIVE_DIR "${CUE4PARSE_DIR}/CUE4Parse-Natives")
	add_subdirectory(${CUE4PARSE_NATIVE_DIR})

	# CUE4Parse C#
	set(CUE4PARSE_NET_DIR "${CUE4PARSE_DIR}/CUE4Parse")
	set(CUE4PARSE_OUTPUT_DIR "${CUE4PARSE_NET_DIR}/bin/$(Configuration)/net8.0")

	add_custom_target(CUE4Parse-Net
		COMMAND dotnet build "${CUE4PARSE_NET_DIR}/CUE4Parse.csproj" 
        --configuration $(Configuration)
		-p:BuildNatives=false
        -p:SkipNativeBuild=true
		-p:CMakeExitCode=0
        --output "${CUE4PARSE_OUTPUT_DIR}"
		WORKING_DIRECTORY "${CUE4PARSE_NET_DIR}"
		COMMENT "Building CUE4Parse C# library"
	)

	# dumper
	include_external_msproject(dbd-dumper "${CMAKE_CURRENT_SOURCE_DIR}/src/dumper/dbd-dumper.csproj")
	set_target_properties(dbd-dumper PROPERTIES VS_PROJECT_TYPE "9A19103F-16F7-4668-BE54-9A1E7A4F7556")
	add_dependencies(dbd-dumper CUE4Parse-Natives CUE4Parse-Net)

	# startup project
	set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT dbd-unlocker)
endif()