#!/bin/bash
#
#  Copyright (c) 2020, The OpenThread Authors.
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#  3. Neither the name of the copyright holder nor the
#     names of its contributors may be used to endorse or promote products
#     derived from this software without specific prior written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#  POSSIBILITY OF SUCH DAMAGE.
#

set -euxo pipefail

readonly OT_MERGED_PROFILES=merged_profiles
readonly OT_GCOV_PREFIX_BASE=ot-run

merge_profiles()
{
    local profile_current="$1"
    local profile_merged="$2"

    [[ -d ${profile_current} ]] || return 0

    local profile_temporary="${profile_merged}.tmp"

    gcov-tool merge "${profile_current}" "${profile_merged}" -o "${profile_temporary}" || return 0
    cp -r "${profile_temporary}"/* "${profile_merged}"
    rm -rf "${profile_temporary}"
}

do_clean()
{
    rm -rfv "${OT_MERGED_PROFILES}" "${OT_GCOV_PREFIX_BASE}" || sudo rm -rfv "${OT_MERGED_PROFILES}" "${OT_GCOV_PREFIX_BASE}"
}

do_collect()
{
    [[ -d ${OT_GCOV_PREFIX_BASE} ]] || return 0
    sudo chown -R "$USER" "${OT_GCOV_PREFIX_BASE}"

    while read -r node_gcda; do
        while read -r build_name; do
            local profile_current="${node_gcda}/$PWD/build/${build_name}"
            local profile_merged="${OT_MERGED_PROFILES}/build/${build_name}"
            if [[ -d ${profile_merged} ]]; then
                merge_profiles "${profile_current}" "${profile_merged}"
                rm -rf "${profile_current}"
            else
                mkdir -p "$(dirname "${profile_merged}")"
                mv "${profile_current}" "${profile_merged}"
            fi
        done < <(ls "${node_gcda}/$PWD/build")
    done < <(find "${OT_GCOV_PREFIX_BASE}" -type d -name 'ot-gcda.*')
}

do_install()
{
    [[ -d ${OT_MERGED_PROFILES} ]] || return 0

    while read -r build_name; do
        local profile_current="build/${build_name}"
        local profile_merged="${OT_MERGED_PROFILES}/build/${build_name}"
        merge_profiles "${profile_current}" "${profile_merged}"
    done < <(ls "build")

    sudo chown -R "$USER" build
    cp -r "${OT_MERGED_PROFILES}"/build/* build
    rm -rf "${OT_MERGED_PROFILES}" "${OT_GCOV_PREFIX_BASE}"
}

main()
{
    case $1 in
        collect)
            do_collect
            ;;
        install)
            do_install
            ;;
        clean)
            do_clean
            ;;
        *)
            false
            ;;
    esac
}

main "$@"
