#!/bin/bash
# -*- coding: utf-8; mode: sh; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=sh:et:sw=4:ts=4:sts=4

# Note:
# This script is sourced by the mpbb wrapper script.
# Do not execute this directly!

install-dependencies-usage() {
    # "prog" is defined in mpbb-help.
    # shellcheck disable=SC2154
    cat <<EOF
usage: $prog [<global opts>] install-dependencies <port>

Build and install the dependencies of the given port.

Run \`$prog help' for global options and a list of other subcommands.
EOF
}

get-maintainers() {
    # $option_prefix is set in mpbb
    # shellcheck disable=SC2154
    "${option_prefix}/bin/port" info --index --maintainers --line "$@" | tr ',' '\n' | sort | uniq | tr '\n' ',' | \
        awk '{gsub(/(open|no)maintainer(@macports.org)?,/, ""); print}' | \
        tr '$' '\n' | sed 's/,$//' | tr '@' ';'
}

install-dependencies() {
    local port=${1-}
    if [[ -z $port ]]; then
        err "Must specify a port"
        return 1
    fi
    local dependencies
    local dependencies_count
    local dependencies_counter
    local depname
    local depvariants
    local failcachecounter
    # $option_log_dir is set in mpbb
    # shellcheck disable=SC2154
    local log_status_dependencies="${option_log_dir}/dependencies-progress.txt"
    local log_subports_progress="${option_log_dir}/ports-progress.txt"

    # prepare the log file and make sure to start with an empty one
    mkdir -p "${option_log_dir}"
    > "$log_status_dependencies"

    # calculate list of dependencies in-order
    # $option_prefix and $thisdir are set in mpbb
    # shellcheck disable=SC2154
    dependencies=$("${option_prefix}/bin/port-tclsh" "${thisdir}/tools/dependencies.tcl" "$@")
    if [ $? -ne 0 ]; then
        echo "Calculating dependencies for '$port' failed, aborting." >&2
        echo "Building '$port' ... [ERROR] (failed to calculate dependencies) maintainers: $(get-maintainers "$port")." >> "$log_subports_progress"
        return 1
    fi

    if [ -z "$dependencies" ]; then
        echo "'$port' has no dependencies, continuing." >&2
        return 0
    fi

    dependencies_count=$(echo "$dependencies" | wc -l | sed 's/ *//g')
    dependencies_counter=1

    echo "Installing $dependencies_count dependencies of $port:" | tee -a "$log_status_dependencies"
    echo "$dependencies" | sed -E 's/^/ - /' | tee -a "$log_status_dependencies"
    echo >> "$log_status_dependencies"

    # Check whether any of the dependencies have previously failed
    failcachecounter=0
    while read -r dependency; do
        # Split portname +variant1+variant2 into portname and variants, where
        # the variants are optional.
        depname=${dependency%% *}
        depvariants=${dependency:${#depname}+1}

        # $depvariants isn't quoted on purpose
        # shellcheck disable=SC2086
        if ! failcache_test "$depname" $depvariants; then
            text="Dependency '${depname}' with variants '${depvariants}' has previously failed and is required."
            echo "$text" >&2
            echo "$text" >> "$log_status_dependencies"
            echo "Building '$port' ... [ERROR] (failed to install dependency '${depname}') maintainers: $(get-maintainers "$port" "${depname}")." >> "$log_subports_progress"
            failcachecounter=$((failcachecounter + 1))
        fi
    done <<<"$dependencies"

    if [ $failcachecounter -gt 0 ]; then
        echo "Aborting build because $failcachecounter dependencies are known to fail." >&2
        return 1
    fi

    while read -r dependency; do
        # Split portname +variant1+variant2 into portname and variants, where
        # the variants are optional.
        depname=${dependency%% *}
        depvariants=${dependency:${#depname}+1}

        text="Installing dependency ($dependencies_counter of $dependencies_count) '${depname}' with variants '${depvariants}'"
        echo "----> ${text}"
        echo -n "${text} ... " >> "$log_status_dependencies"
        # $depvariants isn't quoted on purpose
        # shellcheck disable=SC2086
        if ! "${option_prefix}/bin/port" -d install --unrequested "$depname" $depvariants; then
            echo "Build of dependency '${depname}' with variants '${depvariants}' failed, aborting." >&2
            echo "[FAIL]" >> "$log_status_dependencies"
            echo "Building '$port' ... [ERROR] (failed to install dependency '${depname}') maintainers: $(get-maintainers "$port" "${depname}")." >> "$log_subports_progress"

            # Update failcache
            # $depvariants isn't quoted on purpose
            # shellcheck disable=SC2086
            failcache_failure "$depname" $depvariants
            if [ $? -ne 0 ]; then
                err "failcache_failure $depname $depvariants failed."
                return 1
            fi
            return 1
        else
            echo "[OK]" >> "$log_status_dependencies"
            # Remove failcache if it exists
            # $depvariants isn't quoted on purpose
            # shellcheck disable=SC2086
            failcache_success "$depname" $depvariants
            if [ $? -ne 0 ]; then
                err "failcache_success $depname $depvariants failed."
                return 1
            fi
            dependencies_counter=$((dependencies_counter + 1))
        fi
    done <<<"$dependencies"
}