#!/bin/bash -efu

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See LICENSE for more details.
#
# Copyright: Red Hat Inc. 2019, 2023
# Author: Andrei Stepanov <astepano@redhat.com>


: "${PROG:=${0##*/}}"

# Source `mtps-setup' from $PATH
if command -v "mtps-setup" >/dev/null; then source "mtps-setup"; fi
# If previous fails source `mtps-setup` from this script dir
if [ -z "${YUMDNFCMD:-}" ]; then source "$(dirname "${BASH_SOURCE[0]}")/mtps-setup" || ( echo "Cannot source mtps-setup" >&2; exit 91 ); fi

msg_usage() {
    cat << EOF
Usage:
$PROG <options>

Options:
-m, --mmd=FILE                               Module meta data yaml file, can be .gz
-h, --help                                   display this help and exit
-v, --verbose                                print debug messages
EOF
}

box_out() {
    local s=("$@")
    local b=
    local w=
    for l in "${s[@]}"; do
        ((w<${#l})) && { b="$l"; w="${#l}"; }
    done
    echo -e " -${b//?/-}-\n| ${b//?/ } |"
    for l in "${s[@]}"; do
        printf '| %*s |\n' "-$w" "$l"
    done
    echo -e "| ${b//?/ } |\n-${b//?/-}-"
}

opt_str="$@"
opt=$(getopt -n "$0" --options "hvt:s:m:" --longoptions "help,verbose,mmd:,test:,selinux:" -- "$@")
eval set -- "$opt"
while [[ $# -gt 0 ]]; do
    case "$1" in
        -m|--mmd)
            MMD="$2"
            shift 2
            ;;
        -v|--verbose)
            DEBUG="-v"
            shift
            ;;
        -h|--help)
            msg_usage
            exit 0
            ;;
        --)
            shift
            ;;
        *)
            msg_usage
            exit 1
    esac
done


# Entry

: "${DEBUG:=}"

debug "MMD: ${MMD:=}"
debug "Use ${YUMDNFCMD}"

# Test correct invocation
if [ -z "$MMD" ]; then
    echo "Use: $PROG -h for help."
    exit
fi

START_DATE="$(date '+%x')"
START_TIME="$(date '+%T')"

IFS=$'\r\n' GLOBIGNORE='*' command eval  'requires=($(mtps-mutils --modulemd "$MMD" --getrequires))'

requires_list=()
for i in "${requires[@]}"; do
    i="${i## }"
    i="${i%% }"
    requires_list+=("   * ${i// / or }")
done
box_out "# DEPENDENCY" "" "Modules to be enabled:" "" "${requires_list[@]:-}"

# Prefix all files with common suffix
TESTRUN_ID="$(date +%H%M%S)"

# Put logs by default at CWD/mtps-logs
mkdir -p "${LOGS_DIR:=mtps-logs}"

for require in "${requires[@]}"; do
    ret=1
    for name_stream in $require; do
        name=${name_stream%%:*}
        stream=${name_stream##*:}
        # Make 1 sec between audit entries
        NEW_START_TIME="$(date '+%T')"
        if [ "$NEW_START_TIME" = "$START_TIME" ]; then
            sleep 1
            NEW_START_TIME="$(date '+%T')"
        fi
        START_TIME="$NEW_START_TIME"
        box_out \
            "Enabling required module" \
            "======================" \
            "" \
            "  Name:        $name" \
            "  Stream:      $stream"
        logfname="${LOGS_DIR%%/}/${TESTRUN_ID}-enable-${name}-${stream}.log"
        debug "Resetting module: $name" | tee -a "$logfname"
        "${YUMDNFCMD}" -y module reset "$name" 2>&1 | tee -a "$logfname"
        test_status="${PIPESTATUS[0]}"
        if [ "$test_status" -eq "0" ]; then
            debug "Enabling module: ${name}:${stream}" | tee -a "$logfname"
            "${YUMDNFCMD}" -y module enable "${name}:${stream}" 2>&1 | tee -a "$logfname"
            test_status="${PIPESTATUS[0]}"
        fi
        if [ "$test_status" -ne "0" ]; then
            new_logfname="$(dirname "$logfname")/FAIL-$(basename "$logfname")"
        else
            new_logfname="$(dirname "$logfname")/PASS-$(basename "$logfname")"
            ret=0
        fi
        mv "$logfname" "$new_logfname"
        if [ "$test_status" -eq "0" ]; then
            ret=0
            echo "Requirements are satisfied: ${require// / or }"
            break
        fi
    done
    if [ "$ret" -ne "0" ]; then
        echo "Fail to meet module dependency. No one can be enabled from: ${require// / or }"
        exit 1
    fi
done

exit 0
