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

#[===[.rst:
Coverage CMake module
---------------------

Control flow
^^^^^^^^^^^^

Using the code coverage feature of the system starts with including
``Coverage`` module. This will implicitly check if all the requirements for
generating coverage are fulfilled. This includes checking the following
conditions.

- Compiler is GCC
- lcov executables exist
- ``c-picker-coverage-mapper`` is available

As the next step it sets the compiler flags to make GCC to generate binaries
with coverage information.


Variables
^^^^^^^^^

The module sets the following variables while it's checking its prerequisites.

.. cmake:variable:: LCOV_COMMAND

Path of lcov executable

.. cmake:variable:: GENHTML_COMMAND

Path of genhtml executable which is part of the lcov package.

.. cmake:variable:: CPICKER_COVERAGE_MAPPER_COMMAND

Path of ``c-picker-coverage-mapper`` executable which is provided by c-picker
pip package.


Functions
^^^^^^^^^

The module also contains functions for setting up the coverage feature.

#]===]

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()

#[===[.rst:
.. cmake:command:: coverage_generate

  .. code-block:: cmake

    coverage_generate(
    	NAME test_name
    	SOURCE_DIR source_directory
    	BINARY_DIR binary_directory
    	CPICKER_MAPPING_PATH c_picker_mapping_path
    	OUTPUT_FILE output_file
    )

  The function outputs an lcov info file for further processing. It also handles
  the remapping of the coverage of the c-picker generated files.

  Control flow:

  1. Running the ``lcov`` command for collecting the coverage data from the
     available ``.gcda`` and ``.gcno`` files in the ``BINARY_DIR``.

  2. The output of previous step is processed by ``c-picker-coverage-mapper``.
     This will remap the coverage of files in ``CPICKER_MAPPING_PATH`` to the
     original source files.

  3. Adds the output file to the ``coverage`` target's dependency list.

  Inputs:

  ``NAME``
    Test name included in lcov info file

  ``SOURCE_DIR``
    Directory of source files

  ``BINARY_DIR``
    Directory of the ``.gcda`` and ``.gcno`` files

  ``CPICKER_MAPPING_PATH``
    Path of c-picker generated files

  ``OUTPUT_FILE``
    Output lcov coverage info file

#]===]
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()

#[===[.rst:
.. cmake:command:: coverage_filter

  .. code-block:: cmake

    coverage_filter(
    	INPUT_FILE input_file
    	OUTPUT_FILE output_file
    	INCLUDE_DIRECTORY include_directory
    )

  The function filters the coverage data by including only the coverage of the
  files of ``INCLUDE_DIRECTORY`` or its subdirectories. It adds the filtered
  output file to the ``coverage`` target's dependency list.

  Inputs:

  ``INPUT_FILE``
    Input lcov coverage info file

  ``OUTPUT_FILE``
    Output lcov coverage info file

  ``INCLUDE_DIRECTORY``
    Root directory of included files

#]===]
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()

#[===[.rst:
.. cmake:command:: coverage_generate_report

  .. code-block:: cmake

    coverage_generate_report(
    	INPUT_FILE input_file
    	OUTPUT_DIRECTORY output_directory
    )

  The function generates a HTML coverage report from the lcov info file into
  the ``OUTPUT_DIRECTORY``. It adds the output directory to the
  ``coverage_report`` target's dependency list.

  Inputs:

  ``INPUT_FILE``
    Input lcov coverage info file

  ``OUTPUT_DIRECTORY``
    Output directory of the coverage report where the ``index.html`` is the
    root file of the report.

#]===]
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()
