#[[
    Run this file from its current folder in script mode, with triplet as a parameter:
        cmake -P build_from_scratch.cmake <triplet>
    It will set up and build 3rdparty in a folder next to the SDK repo, and also
    build the SDK against those 3rd party libraries.
    pdfium must be supplied manually, or it can be commented out in preferred-ports-sdk.txt
]]

function(usage_exit err_msg)
    message(FATAL_ERROR
"${err_msg}
Build from scratch helper script usage:
    cmake -P build_from_scratch.cmake <triplet>
Script must be run from its current folder")
endfunction()

get_filename_component(_prog_name ${CMAKE_ARGV2} NAME)
set(_script_cwd ${CMAKE_CURRENT_SOURCE_DIR})

if(NOT EXISTS "${_script_cwd}/${_prog_name}")
    usage_exit("Script was not run from its containing directory")
endif()

if(NOT CMAKE_ARGV3)
    usage_exit("Triplet was not provided")
endif()

set(_triplet ${CMAKE_ARGV3})
set(_sdk_dir "${_script_cwd}/../..")

message(STATUS "Building for triplet ${_triplet} with SDK dir ${_sdk_dir}")

set (_3rdparty_sdk_dir "${_sdk_dir}/../3rdparty_sdk")

file(MAKE_DIRECTORY ${_3rdparty_sdk_dir})

set(CMAKE_EXECUTE_PROCESS_COMMAND_ECHO STDOUT)

set(_cmake ${CMAKE_COMMAND})

function(execute_checked_command)
    execute_process(
        ${ARGV}
        RESULT_VARIABLE _result
        ERROR_VARIABLE _error
    )

    if(_result)
        message(FATAL_ERROR "Execute_process command had nonzero exit code ${_result} with error ${_error}")
    endif()
endfunction()

# Configure and build the build3rdparty tool

execute_checked_command(
    COMMAND ${_cmake}
        -S ${_script_cwd}/build3rdParty
        -B ${_3rdparty_sdk_dir}
        -DCMAKE_BUILD_TYPE=Release
)

execute_checked_command(
    COMMAND ${_cmake}
        --build ${_3rdparty_sdk_dir}
        --config Release
)

# Use the prep tool to set up just our dependencies and no others

if(WIN32)
    set(_3rdparty_tool_exe "${_3rdparty_sdk_dir}/Release/build3rdParty.exe")
    set(_3rdparty_vcpkg_dir "${_3rdparty_sdk_dir}/Release/vcpkg/")
else()
    set(_3rdparty_tool_exe "${_3rdparty_sdk_dir}/build3rdParty")
    set(_3rdparty_vcpkg_dir "${_3rdparty_sdk_dir}/vcpkg/")
endif()

set(_3rdparty_tool_common_args
    --ports "${_script_cwd}/preferred-ports-sdk.txt"
    --triplet ${_triplet}
    --sdkroot ${_sdk_dir}
)

execute_checked_command(
    COMMAND ${_3rdparty_tool_exe}
        --setup
        --removeunusedports
        --nopkgconfig
        ${_3rdparty_tool_common_args}
    WORKING_DIRECTORY ${_3rdparty_sdk_dir}
)

execute_checked_command(
    COMMAND ${_3rdparty_tool_exe}
        --build
        ${_3rdparty_tool_common_args}
    WORKING_DIRECTORY ${_3rdparty_sdk_dir}
)

# Allows use of the VCPKG_XXXX variables defined in the triplet file
# We search our own custom triplet folder, and then the standard ones searched by vcpkg
foreach(_triplet_dir
    "${_script_cwd}/vcpkg_extra_triplets/"
    "${_3rdparty_vcpkg_dir}/triplets/"
    "${_3rdparty_vcpkg_dir}/triplets/community"
)
    set(_triplet_file "${_triplet_dir}/${_triplet}.cmake")
    if(EXISTS ${_triplet_file})
        message(STATUS "Using triplet ${_triplet} at ${_triplet_file}")
        include(${_triplet_file})
        set(_triplet_file_found 1)
        break()
    endif()
endforeach()

if(NOT _triplet_file_found)
    message(FATAL_ERROR "Could not find triplet ${_triplet} in Mega vcpkg_extra_triplets nor in vcpkg triplet folders")
endif()

# Now set up to build this repo
# Logic between Windows and other platforms diverges slightly here:
# in the CMake paradigm, Visual Studio is what's called a multi-configuration generator,
# meaning we can do separate builds (Debug, Release) from one configuration.
# The default generators on *nix platforms (Ninja, Unix Makefiles) are single-config, so we
# configure once for each build type
# In a future extension, we may wish to have users provide the configs as a semicolon-separated list

set(_common_cmake_args
    "-DMega3rdPartyDir=${_3rdparty_sdk_dir}"
    "-DVCPKG_TRIPLET=${_triplet}"
    -DUSE_THIRDPARTY_FROM_VCPKG=1
    -S ${_script_cwd}
)

if(WIN32)
    if(_triplet MATCHES "staticdev$")
        set(_extra_cmake_args -DMEGA_LINK_DYNAMIC_CRT=0 -DUNCHECKED_ITERATORS=1)
    endif()

    if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x86")
        set(_arch "Win32")
    else()
        set(_arch ${VCPKG_TARGET_ARCHITECTURE})
    endif()

    set(_toolset ${VCPKG_PLATFORM_TOOLSET})
    set(_build_dir "${_sdk_dir}/build-${_triplet}")

    file(MAKE_DIRECTORY ${_build_dir})

    execute_checked_command(
        COMMAND ${_cmake}
            -G "Visual Studio 16 2019"
            -A ${_arch}
            # Could also pass -T VCPKG_PLATFORM_TOOLSET
            -B ${_build_dir}
            ${_common_cmake_args}
            ${_extra_cmake_args}
    )

    foreach(_config "Debug" "Release")
        execute_checked_command(
            COMMAND ${_cmake}
                --build ${_build_dir}
                --config ${_config}
                --parallel 4
        )
    endforeach()
else()
    foreach(_config "Debug" "Release")
        set(_build_dir "${_sdk_dir}/build-${_triplet}-${_config}")
        file(MAKE_DIRECTORY ${_build_dir})

        execute_checked_command(
            COMMAND ${_cmake}
                ${_common_cmake_args}
                -B ${_build_dir}
                "-DCMAKE_BUILD_TYPE=${_config}"
        )

        execute_checked_command(
            COMMAND ${_cmake}
                --build ${_build_dir}
                --parallel 4
        )
    endforeach()
endif()
