#
# MIT License
#
# Copyright 2017 Launchpad project contributors (see COPYRIGHT.md)
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
set(RELEASE 0)
set(DEBUG 0)

if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release" OR "${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
    set(RELEASE 1)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
    set(DEBUG 2)
else ()
    set(DEBUG 1)
endif ()

macro(symlink source destination)
    if (NOT EXISTS ${destination})
        get_filename_component(DESTINATION_DIR "${destination}" DIRECTORY)
        file(MAKE_DIRECTORY ${DESTINATION_DIR})
        execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${source} ${destination})
    endif ()
endmacro()

macro(replace_cflag flag replacement)
    set(COMPILER_FLAGS
        CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO
        CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO
        )
    foreach (CompilerFlag ${COMPILER_FLAGS})
        string(REPLACE "${flag}" "${replacement}" ${CompilerFlag} "${${CompilerFlag}}")
    endforeach ()
endmacro()

macro(add_compiler_flags)
    cmake_parse_arguments(PARAM "C;CXX;DEBUG;RELEASE;RELWITHDEBINFO;MINSIZEREL" "" "" ${ARGN})
    set(PARAM_UNPARSED_ARGUMENTS "${PARAM_UNPARSED_ARGUMENTS}")
    string(REPLACE ";" " " PARAM_UNPARSED_ARGUMENTS "${PARAM_UNPARSED_ARGUMENTS}")

    if (PARAM_DEBUG)
        if (PARAM_C OR NOT PARAM_C AND NOT PARAM_CXX)
            set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_CXX OR NOT PARAM_C AND NOT PARAM_CXX)
            set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
    endif ()
    if (PARAM_RELWITHDEBINFO)
        if (PARAM_C OR NOT PARAM_C AND NOT PARAM_CXX)
            set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_CXX OR NOT PARAM_C AND NOT PARAM_CXX)
            set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
    endif ()
    if (PARAM_RELEASE)
        if (PARAM_C OR NOT PARAM_C AND NOT PARAM_CXX)
            set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_CXX OR NOT PARAM_C AND NOT PARAM_CXX)
            set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
    endif ()
    if (PARAM_MINSIZEREL)
        if (PARAM_C OR NOT PARAM_C AND NOT PARAM_CXX)
            set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_CXX OR NOT PARAM_C AND NOT PARAM_CXX)
            set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
    endif ()
    if (NOT PARAM_DEBUG AND NOT PARAM_MINSIZEREL AND NOT PARAM_RELEASE AND NOT PARAM_RELWITHDEBINFO)
        if (PARAM_C OR (NOT PARAM_C AND NOT PARAM_CXX))
            set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_CXX OR (NOT PARAM_C AND NOT PARAM_CXX))
            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
    endif ()
endmacro()

macro(add_linker_flags)
    cmake_parse_arguments(PARAM "EXE;SHARED;STATIC;MODULE;DEBUG;RELEASE;RELWITHDEBINFO;MINSIZEREL" "" "" ${ARGN})
    set(PARAM_UNPARSED_ARGUMENTS "${PARAM_UNPARSED_ARGUMENTS}")
    string(REPLACE ";" " " PARAM_UNPARSED_ARGUMENTS "${PARAM_UNPARSED_ARGUMENTS}")

    if (PARAM_DEBUG)
        if (PARAM_EXE OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_SHARED OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_STATIC OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "${CMAKE_STATIC_LINKER_FLAGS_DEBUG} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_MODULE OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
    endif ()
    if (PARAM_RELWITHDEBINFO)
        if (PARAM_EXE OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_SHARED OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_STATIC OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_MODULE OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
    endif ()
    if (PARAM_RELEASE)
        if (PARAM_EXE OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_SHARED OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_STATIC OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_MODULE OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
    endif ()
    if (PARAM_MINSIZEREL)
        if (PARAM_EXE OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_SHARED OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_STATIC OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL "${CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_MODULE OR NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE)
            set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "${CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
    endif ()

    if (NOT PARAM_DEBUG AND NOT PARAM_MINSIZEREL AND NOT PARAM_RELEASE AND NOT PARAM_RELWITHDEBINFO)
        if (PARAM_EXE OR (NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE))
            set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_SHARED OR (NOT PARAM_EXE AND NOT PARAM_SHARED AND NOT PARAM_STATIC AND NOT PARAM_MODULE))
            set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_STATIC)
            set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
        if (PARAM_MODULE)
            set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${PARAM_UNPARSED_ARGUMENTS}")
        endif ()
    endif ()
endmacro()