# Get all propreties that cmake supports
execute_process(COMMAND cmake --help-property-list OUTPUT_VARIABLE CMAKE_PROPERTY_LIST)

# Convert command output into a CMake list
string(REGEX
       REPLACE ";"
               "\\\\;"
               CMAKE_PROPERTY_LIST
               "${CMAKE_PROPERTY_LIST}")
string(REGEX
       REPLACE "\n"
               ";"
               CMAKE_PROPERTY_LIST
               "${CMAKE_PROPERTY_LIST}")

function(print_properties)
    message("CMAKE_PROPERTY_LIST = ${CMAKE_PROPERTY_LIST}")
endfunction(print_properties)

function(print_target_properties tgt)
    if(NOT TARGET ${tgt})
        message("There is no target named '${tgt}'")
        return()
    endif()

    set(PROPERTIES_LIST "")
    foreach(prop ${CMAKE_PROPERTY_LIST})
        string(REPLACE "<CONFIG>"
                       "${CMAKE_BUILD_TYPE}"
                       prop
                       ${prop})
        # Fix https://stackoverflow.com/questions/32197663/how-can-i-remove-the-the-location-property-may-not-be-read-from-target-error-i
        if(prop STREQUAL "LOCATION" OR prop MATCHES "^LOCATION_" OR prop MATCHES "_LOCATION$")
            continue()
        endif()
        # message ("Checking ${prop}")
        get_property(propval TARGET ${tgt} PROPERTY ${prop} SET)
        if(propval)
            get_target_property(propval ${tgt} ${prop})
            #message ("${tgt} ${prop} = ${propval}")
            list(APPEND PROPERTIES_LIST "${tgt} ${prop} = ${propval}")
        endif()
    endforeach(prop)

    foreach(msg ${PROPERTIES_LIST})
        message(STATUS "${msg}")
    endforeach()
endfunction(print_target_properties)

function(get_propagated_target_properties_recursive out_list tgt property)
    if(NOT TARGET ${tgt})
        message("There is no target named '${tgt}'")
        return()
    endif()

    get_property(propval TARGET ${tgt} PROPERTY INTERFACE_LINK_LIBRARIES SET)
    if(propval)
        get_target_property(LINK_LIBRARIES ${tgt} INTERFACE_LINK_LIBRARIES)
    else()
        return()
    endif()

    set(property_list "")
    foreach(library ${LINK_LIBRARIES})
        if(NOT TARGET ${library})
            continue()
        endif()

        get_property(propval TARGET ${library} PROPERTY ${property} SET)
        #message("Checking library ${library} : ${${out_list}}")
        if(propval)
            get_target_property(propval ${library} ${property})
            list(APPEND property_list ${propval})
        endif()

        set(tmp_extra "")
        get_propagated_target_properties_recursive(tmp_extra ${library} ${property})
        list(APPEND property_list ${tmp_extra})
    endforeach(library)

    set(${out_list} ${property_list} PARENT_SCOPE)
    list(REMOVE_DUPLICATES ${out_list})
endfunction(get_propagated_target_properties_recursive)

function(get_propagated_target_properties out_list tgt property)
    get_propagated_target_properties_recursive(out ${tgt} ${property})
    list(REMOVE_DUPLICATES out)
    set(${out_list} ${out} PARENT_SCOPE)
endfunction(get_propagated_target_properties)

function(get_mcpu mcpu_out target)
    get_propagated_target_properties(target_properties ${target} INTERFACE_COMPILE_OPTIONS)

    foreach(item ${target_properties})
        string(REGEX MATCH
                     "^-mcpu=(.+)$"
                     MCPU
                     ${item})
        if(MCPU)
            set(${mcpu_out} ${CMAKE_MATCH_1} PARENT_SCOPE)
        endif()
    endforeach()
endfunction()


function(get_linked_libraries out_list tgt)
    if(NOT TARGET ${tgt})
        message("There is no target named '${tgt}'")
        return()
    endif()

    get_property(propval TARGET ${tgt} PROPERTY TYPE)
    if(NOT propval STREQUAL "EXECUTABLE")
        message(FATAL_ERROR "Can not use get_linked_libraries on non-executable target '${tgt}' [${propval}]")
        return()
    endif()

    get_target_property(LINK_LIBRARIES ${tgt} LINK_LIBRARIES)
    #list(FILTER LINK_LIBRARIES INCLUDE REGEX "FreeRTOS")

    set(ALL_LINK_LIBRARIES ${LINK_LIBRARIES})
    foreach(library ${LINK_LIBRARIES})
        if(NOT TARGET ${library})
            continue()
        endif()

        get_property(propval TARGET ${library} PROPERTY INTERFACE_LINK_LIBRARIES SET)
        if(propval)
            get_target_property(propval ${library} INTERFACE_LINK_LIBRARIES)
            list(APPEND ALL_LINK_LIBRARIES ${propval})
        endif()
    endforeach(library)

    set(${out_list} ${ALL_LINK_LIBRARIES} PARENT_SCOPE)
    list(REMOVE_DUPLICATES ${out_list})
endfunction()