#
# Copyright (c) 2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#

include_guard(DIRECTORY)

# Checking GCC
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
	message(FATAL_ERROR "Coverage measurement is only supported when using GCC")
endif()

# Checking lcov
find_program(LCOV_COMMAND "lcov")
if (NOT LCOV_COMMAND)
	message(FATAL_ERROR "Please install lcov")
endif()

# Checking c-picker-coverage-mapper
find_program(CPICKER_COVERAGE_MAPPER_COMMAND "c-picker-coverage-mapper")
if (NOT CPICKER_COVERAGE_MAPPER_COMMAND)
	message(FATAL_ERROR "Please install c-picker-coverage-mapper using pip (part of c-picker)")
endif()

# Checking genhtml
find_program(GENHTML_COMMAND "genhtml")
if (NOT GENHTML_COMMAND)
	message(FATAL_ERROR "Please install genhtml with genhtml (part of lcov)")
endif()

# Including this file enables code coverage measurement by adding the necessary compiler and
# linker flags.
set(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
set(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage -fno-exceptions")
set(CMAKE_EXE_LINKER_FLAGS "-fprofile-arcs -ftest-coverage")

# Adding custom targets
add_custom_target(coverage)
add_custom_target(coverage_report)

# Adds a file to the dependency list of the target by inserting an accessory
# custom target. The name of the custom target is properly escaped.
function(add_coverage_dependency)
	set(_OPTIONS_ARGS)
	set(_ONE_VALUE_ARGS TARGET DEPENDS)
	set(_MULTI_VALUE_ARGS)
	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})

	set(TARGET ${_MY_PARAMS_TARGET})
	set(DEPENDS ${_MY_PARAMS_DEPENDS})

	string(REGEX REPLACE "\\/" "_" CUSTOM_TARGET_SUFFIX ${DEPENDS})

	add_custom_target(${TARGET}_target_${CUSTOM_TARGET_SUFFIX} DEPENDS ${DEPENDS})
	add_dependencies(${TARGET} ${TARGET}_target_${CUSTOM_TARGET_SUFFIX})
endfunction()

# Generates LCOV coverage info file by processing the .gcda and .gcno files.
# The function also maps coverage of the c-picker generated files to the original source lines
function(coverage_generate)
	set(_OPTIONS_ARGS)
	set(_ONE_VALUE_ARGS NAME SOURCE_DIR BINARY_DIR CPICKER_MAPPING_PATH OUTPUT_FILE)
	set(_MULTI_VALUE_ARGS)
	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})

	set(TEST_NAME ${_MY_PARAMS_NAME})
	set(SOURCE_DIR ${_MY_PARAMS_SOURCE_DIR})
	set(BINARY_DIR ${_MY_PARAMS_BINARY_DIR})
	set(CPICKER_MAPPING_PATH ${_MY_PARAMS_CPICKER_MAPPING_PATH})
	set(TEMP_FILE ${_MY_PARAMS_OUTPUT_FILE}_temp)
	set(OUTPUT_FILE ${_MY_PARAMS_OUTPUT_FILE})

	# Collecting information from .gcda and .gcno files into an lcov .info file
	# Mapping c-picker generated files' coverage info to the original source lines
	add_custom_command(
		OUTPUT ${TEMP_FILE} ${OUTPUT_FILE}
		COMMAND ${LCOV_COMMAND}
			--capture
			--test-name ${TEST_NAME}
			--directory ${BINARY_DIR}
			--base-directory ${SOURCE_DIR}
			--output-file ${TEMP_FILE}
		COMMAND ${CPICKER_COVERAGE_MAPPER_COMMAND}
			--input ${TEMP_FILE}
			--output ${OUTPUT_FILE}
			--mapping-path ${CPICKER_MAPPING_PATH}
	)

	add_coverage_dependency(
		TARGET coverage
		DEPENDS ${OUTPUT_FILE}
	)
endfunction()

# Filters coverage info of files from the matching directory
function(coverage_filter)
	set(_OPTIONS_ARGS)
	set(_ONE_VALUE_ARGS INPUT_FILE OUTPUT_FILE INCLUDE_DIRECTORY)
	set(_MULTI_VALUE_ARGS)
	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})

	set(INPUT_FILE ${_MY_PARAMS_INPUT_FILE})
	set(OUTPUT_FILE ${_MY_PARAMS_OUTPUT_FILE})
	set(INCLUDE_DIRECTORY ${_MY_PARAMS_INCLUDE_DIRECTORY})

	# The pattern must be an absolute path ending with an asterisk
	get_filename_component(INCLUDE_DIRECTORY_ABSPATH "${INCLUDE_DIRECTORY}" ABSOLUTE)
	set(INCLUDE_DIRECTORY_ABSPATH "${INCLUDE_DIRECTORY_ABSPATH}/*")

	add_custom_command(
		OUTPUT ${OUTPUT_FILE}
		COMMAND ${LCOV_COMMAND}
			--extract ${INPUT_FILE} \"${INCLUDE_DIRECTORY_ABSPATH}\"
			--output-file ${OUTPUT_FILE}
		DEPENDS ${INPUT_FILE}
	)

	add_coverage_dependency(
		TARGET coverage
		DEPENDS ${OUTPUT_FILE}
	)
endfunction()

# Generated an HTML report from the LCOV info file
function(coverage_generate_report)
	set(_OPTIONS_ARGS)
	set(_ONE_VALUE_ARGS INPUT_FILE OUTPUT_DIRECTORY)
	set(_MULTI_VALUE_ARGS)
	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})

	set(INPUT_FILE ${_MY_PARAMS_INPUT_FILE})
	set(OUTPUT_DIRECTORY ${_MY_PARAMS_OUTPUT_DIRECTORY})

	add_custom_command(
		OUTPUT ${OUTPUT_DIRECTORY}
		COMMAND genhtml ${INPUT_FILE}
			--show-details
			--output-directory ${OUTPUT_DIRECTORY}
		DEPENDS ${INPUT_FILE}
	)

	add_coverage_dependency(
		TARGET coverage_report
		DEPENDS ${OUTPUT_DIRECTORY}
	)
endfunction()
