#!/usr/bin/env bash
set -e

TOOLCHAINS_CSV='support/config-fragments/autobuild/toolchain-configs.csv'

main() {
    local o O opts
    local cfg dir pkg random toolchains_dir toolchain
    local ret nb nb_skip nb_fail nb_legal nb_tc build_dir
    local -a toolchains

    o='hc:d:p:r:t:'
    O='help,config-snippet:build-dir:package:,random:,toolchains-dir:'
    opts="$(getopt -n "${my_name}" -o "${o}" -l "${O}" -- "${@}")"
    eval set -- "${opts}"

    random=0
    toolchains_csv="${TOOLCHAINS_CSV}"
    while [ ${#} -gt 0 ]; do
        case "${1}" in
        (-h|--help)
            help; exit 0
            ;;
        (-c|--config-snippet)
            cfg="${2}"; shift 2
            ;;
        (-d|--build-dir)
            dir="${2}"; shift 2
            ;;
        (-p|--package)
            pkg="${2}"; shift 2
            ;;
        (-r|--random)
            random="${2}"; shift 2
            ;;
        (-t|--toolchains-csv)
            toolchains_csv="${2}"; shift 2
            ;;
        (--)
            shift; break
            ;;
        esac
    done
    if [ -z "${cfg}" ]; then
        printf "error: no config snippet specified\n" >&2; exit 1
    fi
    if [ ! -e "${cfg}" ]; then
        printf "error: %s: no such file\n" "${cfg}" >&2; exit 1
    fi
    if [ -z "${dir}" ]; then
        dir="${HOME}/br-test-pkg"
    fi

    # Extract the URLs of the toolchains; drop internal toolchains
    # E.g.: http://server/path/to/name.config,arch,libc
    #  -->  http://server/path/to/name.config
    toolchains=($(sed -r -e 's/,.*//; /internal/d; /^#/d; /^$/d;' "${toolchains_csv}" \
                  |if [ ${random} -gt 0 ]; then \
                      sort -R |head -n ${random}
                   else
                      cat
                   fi |sort
                 )
               )

    nb_tc="${#toolchains[@]}"
    if [ ${nb_tc} -eq 0 ]; then
        printf "error: no toolchain found (networking issue?)\n" >&2; exit 1
    fi

    nb=0
    nb_skip=0
    nb_fail=0
    nb_legal=0
    for toolchainconfig in "${toolchains[@]}"; do
        : $((nb++))
        toolchain="$(basename "${toolchainconfig}" .config)"
        build_dir="${dir}/${toolchain}"
        printf "%40s [%*d/%d]: " "${toolchain}" ${#nb_tc} ${nb} ${nb_tc}
        build_one "${build_dir}" "${toolchainconfig}" "${cfg}" "${pkg}" && ret=0 || ret=${?}
        case ${ret} in
        (0) printf "OK\n";;
        (1) : $((nb_skip++)); printf "SKIPPED\n";;
        (2) : $((nb_fail++)); printf "FAILED\n";;
        (3) : $((nb_legal++)); printf "FAILED\n";;
        esac
    done

    printf "%d builds, %d skipped, %d build failed, %d legal-info failed\n" \
        ${nb} ${nb_skip} ${nb_fail} ${nb_legal}
}

build_one() {
    local dir="${1}"
    local toolchainconfig="${2}"
    local cfg="${3}"
    local pkg="${4}"

    mkdir -p "${dir}"

    support/kconfig/merge_config.sh -O "${dir}" \
        "${toolchainconfig}" "support/config-fragments/minimal.config" "${cfg}" \
        > /dev/null
    # We want all the options from the snippet to be present as-is (set
    # or not set) in the actual .config; if one of them is not, it means
    # some dependency from the toolchain or arch is not available, in
    # which case this config is untestable and we skip it.
    # We don't care about the locale to sort in, as long as both sort are
    # done in the same locale.
    comm -23 <(sort "${cfg}") <(sort "${dir}/.config") >"${dir}/missing.config"
    if [ -s "${dir}/missing.config" ]; then
        return 1
    fi
    # Remove file, it's empty anyway.
    rm -f "${dir}/missing.config"

    if [ -n "${pkg}" ]; then
        if ! make O="${dir}" "${pkg}-dirclean" >> "${dir}/logfile" 2>&1; then
            return 2
        fi
    fi

    # shellcheck disable=SC2086
    if ! make O="${dir}" ${pkg} >> "${dir}/logfile" 2>&1; then
        return 2
    fi

    # legal-info done systematically, because some packages have different
    # sources depending on the configuration (e.g. lua-5.2 vs. lua-5.3)
    if ! make O="${dir}" legal-info >> "${dir}/logfile" 2>&1; then
        return 3
    fi
}

help() {
    cat <<_EOF_
test-pkg: test-build a package against various toolchains and architectures

The supplied config snippet is appended to each toolchain config, the
resulting configuration is checked to ensure it still contains all options
specified in the snippet; if any is missing, the build is skipped, on the
assumption that the package under test requires a toolchain or architecture
feature that is missing.

In case failures are noticed, you can fix the package and just re-run the
same command again; it will re-run the test where it failed. If you did
specify a package (with -p), the package build dir will be removed first.

The list of toolchains is retrieved from ${TOOLCHAINS_CSV}.
Only the external toolchains are tried, because building a Buildroot toolchain
would take too long. An alternative toolchains CSV file can be specified with
the -t option. This file should have lines consisting of the path to the
toolchain config fragment and the required host architecture, separated by a
comma. The config fragments should contain only the toolchain and architecture
settings.

Options:

    -h, --help
        Print this help.

    -c CFG, --config-snippet CFG
        Use the CFG file as the source for the config snippet. This file
        should contain all the config options required to build a package.

    -d DIR, --build-dir DIR
        Do the builds in directory DIR, one sub-dir per toolchain.

    -p PKG, --package PKG
        Test-build the package PKG, by running 'make PKG'; if not specified,
        just runs 'make'.

    -r N, --random N
        Limit the tests to the N randomly selected toolchains, instead of
        building with all toolchains.

    -t CSVFILE, --toolchains-csv CSVFILE
        CSV file containing the paths to config fragments of toolchains to
        try. If not specified, the toolchains in ${TOOLCHAINS_CSV} will be
        used.

Example:

    Testing libcec would require a config snippet that contains:
        BR2_PACKAGE_LIBCEC=y

    Testing libcurl with openSSL support would require a snippet such as:
        BR2_PACKAGE_OPENSSL=y
        BR2_PACKAGE_LIBCURL=y

_EOF_
}

my_name="${0##*/}"
main "${@}"
