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

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

do_clean() {
    if [ ! -z "${TEMP_CONF}" ]; then
        rm -f "${TEMP_CONF}"
    fi
}

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

    o='hac:d:n: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
    all=0
    number=0
    mode=0
    toolchains_csv="${TOOLCHAINS_CSV}"
    while [ ${#} -gt 0 ]; do
        case "${1}" in
        (-h|--help)
            help; exit 0
            ;;
        (-a|--all)
            all=1; shift 1
            ;;
        (-c|--config-snippet)
            cfg="${2}"; shift 2
            ;;
        (-d|--build-dir)
            dir="${2}"; shift 2
            ;;
        (-n|--number)
            number="${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

    trap do_clean INT TERM HUP EXIT

    if [ -z "${cfg}" ]; then
        pkg_br_name="${pkg//-/_}"
        pkg_br_name="BR2_PACKAGE_${pkg_br_name^^}"
        TEMP_CONF=$(mktemp /tmp/test-${pkg}-config.XXXXXX)
        echo "${pkg_br_name}=y" > ${TEMP_CONF}
        cfg="${TEMP_CONF}"
    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

    if [ ${random} -gt 0 ]; then
        mode=$((mode+1))
    fi

    if [ ${number} -gt 0 ]; then
        mode=$((mode+1))
    fi

    if [ ${all} -eq 1 ]; then
        mode=$((mode+1))
    fi

    # Default mode is to test the N first toolchains, which have been
    # chosen to be a good selection of toolchains.
    if [ ${mode} -eq 0 ] ; then
        number=6
    elif [ ${mode} -gt 1 ] ; then
        printf "error: --all, --number and --random are mutually exclusive\n" >&2; exit 1
    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}
                  elif [ ${number} -gt 0 ]; then \
                      head -n ${number}
                  else
                      sort
                  fi
                 )
               )

    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}"

    CONFIG_= support/kconfig/merge_config.sh -O "${dir}" \
        "${toolchainconfig}" "support/config-fragments/minimal.config" "${cfg}" \
        >> "${dir}/logfile" 2>&1
    # 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 ! BR_FORCE_CHECK_DEPENDENCIES=YES 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.

By default, a useful subset of toolchains is tested. If needed, all
toolchains can be tested (-a), an arbitrary number of toolchains (-n
in order, -r for random).

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'.

    -a, --all
        Test all toolchains, instead of the default subset defined by
        Buildroot developers.

    -n N, --number N
        Test N toolchains, in the order defined in the toolchain CSV
        file.

    -r N, --random N
        Limit the tests to the N randomly selected 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 "${@}"
