if(__UFW_HardwareAbstraction)
  return()
endif()
set(__UFW_HardwareAbstraction 1)

include(SetupTargetCPU)
include(UFWTools)

function(ufw_board_init)
  ufw_get_property(board-objects BOARD_NAME name)
  ufw_get_property(board-objects BOARD_ARCHITECTURE cpu)
  message(STATUS "Setting target board: ${name}")
  message(STATUS "Architecture from board definition: ${cpu}")
  set(PROJECT_TARGET_CPU ${cpu})
  set(PROJECT_TARGET_CPU ${cpu} PARENT_SCOPE)
  if (COMMAND board_init_posthook)
    board_init_posthook()
  endif()
  set_target_cpu(board-objects)
endfunction()

function(define_board name)
  set(__multi_args CONFIG SOURCES LIBRARIES INCLUDE SYSTEM_INCLUDE DEFINITIONS)
  set(__single_args ARCHITECTURE CPUFAMILY CPUHANDLE CPUVENDOR SCRIPT)
  cmake_parse_arguments(PA "" "${__single_args}" "${__multi_args}" ${ARGN})

  set(config    "board-config")
  set(interface "board-interface")
  set(objects   "board-objects")

  if (PA_CONFIG)
    add_library(${config} INTERFACE)
    target_include_directories(${config} INTERFACE ${PA_CONFIG})
  endif()

  add_library(${interface} INTERFACE)
  if (PA_INCLUDE)
    target_include_directories(${interface} INTERFACE ${PA_INCLUDE})
  endif()
  if (PA_SYSTEM_INCLUDE)
    target_include_directories(${interface} SYSTEM INTERFACE ${PA_SYSTEM_INCLUDE})
  endif()
  if (PA_DEFINITIONS)
    target_compile_definitions(${interface} INTERFACE ${PA_DEFINITIONS})
    if (TARGET board-config)
      target_compile_definitions(${config} INTERFACE ${PA_DEFINITIONS})
    endif()
  endif()
  if (PA_LIBRARIES)
    target_link_libraries(${interface} INTERFACE ${PA_LIBRARIES})
  endif()

  if (PA_SOURCES)
    add_library(${objects} OBJECT EXCLUDE_FROM_ALL ${PA_SOURCES})
    target_include_directories(${objects} PUBLIC
      $<TARGET_PROPERTY:${interface},INTERFACE_INCLUDE_DIRECTORIES>)
    target_include_directories(${objects} SYSTEM PUBLIC
      $<TARGET_PROPERTY:${interface},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>)
    target_compile_definitions(${objects} PUBLIC
      $<TARGET_PROPERTY:${interface},INTERFACE_COMPILE_DEFINITIONS>)
  else()
    add_custom_target(${objects})
  endif()

  ufw_set_property(${objects} BOARD_NAME ${name})
  if (PA_ARCHITECTURE)
    ufw_set_property(${objects} BOARD_ARCHITECTURE ${PA_ARCHITECTURE})
  endif()
  if (PA_CPUFAMILY)
    ufw_set_property(${objects} BOARD_CPU_FAMILY ${PA_CPUFAMILY})
  endif()
  if (PA_CPUHANDLE)
    ufw_set_property(${objects} BOARD_CPU_HANDLE ${PA_CPUHANDLE})
  endif()
  if (PA_CPUVENDOR)
    ufw_set_property(${objects} BOARD_CPU_VENDOR ${PA_CPUVENDOR})
  endif()
  if (PA_SCRIPT)
    ufw_set_property(${objects} BOARD_DEFAULT_LINKER_SCRIPT ${PA_SCRIPT})
  endif()
endfunction(define_board)
