#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: t; sh-basic-offset: 4; sh-indentation: 4; tab-width: 8 -*-
script_path="$(dirname ${0})"
script_name="$(basename ${0})"
pbench_bin="$(realpath -e ${script_path}/..)"

# source the base script
. "${pbench_bin}"/base

function usage() {
    printf "usage:\n"
    printf "${script_name} [--help] [--controller=<controller>] [--user=<user>] [--prefix=<path>] [--xz-single-threaded] [--show-server]\n"
}

function missing_arg() {
    printf "\n${script_name}: ${1} is missing its argument\n\n" >&2
    usage >&2
    exit 1
}

# Process options and arguments
opts=$(getopt -q -o c:u:p:xSh --longoptions "controller:,user:,prefix:,xz-single-threaded,show-server,help" -n "getopt.sh" -- "${@}")
if [[ ${?} -ne 0 ]]; then
    printf "\n${script_name}: you specified an invalid option or an unexpected argument\n\n" >&2
    usage >&2
    exit 1
fi

user="${PBENCH_USER}"
controller="${PBENCH_CONTROLLER}"
prefix=""
xz_single_threaded=0
show_server=""
eval set -- "${opts}"
while true; do
    opt="${1}"
    shift
    case "${opt}" in
	-c|--controller)
	    if [[ -n "${1}" ]]; then
		controller="${1}"
		shift;
	    else
		missing_arg "${opt}"
	    fi
	    ;;
	-u|--user)
	    if [[ -n "${1}" ]]; then
		user="${1}"
		shift;
	    else
		missing_arg "${opt}"
	    fi
	    ;;
	-p|--prefix)
	    if [[ -n "${1}" ]]; then
		prefix="${1}"
		shift;
	    else
		missing_arg "${opt}"
	    fi
	    ;;
	-x|--xz-single-threaded)
	    xz_single_threaded=1
	    ;;
	-S|--show-server)
	    show_server="show"
	    ;;
	-h|--help)
	    usage
   	    exit 0
	    ;;
	--)
	    break;
	    ;;
	*)
	    printf "\n${script_name}: you specified an invalid option or an unexpected argument\n\n" >&2
	    usage >&2
	    exit 1
    esac
done

if [[ -z "${controller}" ]]; then
    controller=${full_hostname}
    if [[ -z "${controller}" ]]; then
	error_log "Missing controller name (should be \"hostname -f\" value)"
	exit 1
    fi
fi

# Move into pbench run collection directory
cd ${pbench_run} >/dev/null
if [[ ${?} -ne 0 ]]; then
    error_log "ERROR: pbench local results directory does not exist: ${pbench_run}"
    exit 1
fi

tmp=${pbench_tmp}/${script_name}.${$}
trap "rm -rf ${tmp}" EXIT INT QUIT TERM

# Before we take any further actions, enumerate the results to be moved
mkdir ${tmp}
sts=${?}
if [[ ${sts} -ne 0 ]] ;then
    error_log "Failed: \"mkdir -p ${tmp}\", status ${sts}"
    exit 1
fi
/bin/ls -ort -d */ | awk '{print $8}' | grep -v "^tools-" | grep -v "^tmp/" > ${tmp}/results.lis
if [[ ! -s ${tmp}/results.lis ]]; then
    # Nothing to do
    exit 0
fi

if [[ ! -f "${pbench_bin}/id_rsa" ]]; then
    error_log "ERROR: ${pbench_bin}/id_rsa required for moving results to archive host"
    exit 1
fi

# ask the server where to send the tarballs
results_webserver=$(getconf.py webserver results)
if [[ -z "${results_webserver}" ]]; then
    error_log "ERROR: No web server host configured from which we can fetch the FQDN of the host to which we copy/move results"
    debug_log "\"webserver\" variable in \"results\" section not set"
    exit 1
fi

_info="$(yum info installed pbench-agent 2> /dev/null)"
ver=$(printf -- "%s" "${_info}" | grep Version | awk '{ print $3 }')
if [[ -z "${ver}" ]]; then
    ver="unknown"
fi
rel=$(printf -- "%s" "${_info}" | grep Release | awk '{ print $3 }')
if [[ -z "${rel}" ]]; then
    rel="unknown"
fi
# User-Agent HTTP header: <pbench-agent-ver-rel>:<FQDN>:<$USER>:<full path of this script>""
user_agent="pbench-agent-${ver}-${rel}:${full_hostname}:${USER}:${script_name}"

results_host_info_url=$(getconf.py host_info_url results)
results_host_info=$(curl -s -A "${user_agent}" -L "${results_host_info_url}")
if [[ -z "${results_host_info}" ]]; then
    error_log "ERROR: unable to determine results host info from ${results_host_info_url}"
    debug_log "the curl -A \"${user_agent}\" -L \"${results_host_info_url}\" command failed for some unknown reason"
    exit 1
fi

#
# The results host info should be in the form:
#
#     <results_user>@<results_host(FQDN)>:<results_path>
#
# if the host is up and running, ready to receive results.
#
# If the target host is not ready, then it will provide a one line message of the following form:
#
#     MESSAGE===<text to be display to the user>
#
sysmsg=${results_host_info%%===*}
if [[ "${sysmsg}" = "MESSAGE" ]]; then
    printf -- "*** Message from sysadmins of ${results_webserver}:\n"
    printf -- "***\n*** ${results_host_info##*===}\n"
    printf -- "***\n*** No local actions taken.\n"
    exit 1
fi
results_repo=${results_host_info%%:*}
results_user=${results_repo%%@*}
if [[ -z "${results_user}" ]]; then
    debug_log "Defaulting to \"pbench\" for the \"results_user\""
    results_user="pbench"
    results_host="${results_repo}"
    # Reconstruct the expected results_repo
    results_repo=${results_user}@${results_host}
fi

results_path_prefix=${results_host_info##*:}
if [[ -z "${results_path_prefix}" ]]; then
    error_log "ERROR: fetch results host info did not contain a path prefix: ${results_host_info}"
    debug_log "expected the results_host_info to have the form: <results_user>@<results_host(FQDN)>:<results_path_prefix>"
    exit 1
fi

if [[ ! -z "${show_server}" ]] ;then
    printf -- "${results_repo}\n"
    exit 0
fi

# ssh probe test
ssh -n -i ${pbench_bin}/id_rsa ${ssh_opts} ${results_repo} exit
sts=${?}
if [[ ${sts} -eq 255 ]]; then
    error_log "ERROR: ssh command, \"ssh -n -i ${pbench_bin}/id_rsa ${ssh_opts} ${results_repo} exit\", failed"
    exit 1
elif [[ ${sts} -ne 0 ]]; then
    error_log "ERROR: 'exit' command unexpectedly failed on host ${results_repo} with '${sts}'"
    debug_log "ssh command: \"ssh -n -i ${pbench_bin}/id_rsa ${ssh_opts} ${results_repo} exit\""
    exit 1
fi

let runs_copied=0
let failures=0

mkdir ${tmp}/${controller}
sts=${?}
if [[ ${sts} -ne 0 ]] ;then
    error_log "Failed: \"mkdir -p ${tmp}/${controller}\", status ${sts}"
    exit 1
fi
# We can now start copying tarballs to the server

# Move into pbench run collection directory
pushd ${pbench_run} >/dev/null

while read -r dir; do
    # Before the loop we have created a temp directory, $tmp/$controller, to
    # contain the tarball and the md5 file (as ${tb}.tar.xz.md5.check); pass
    # that information on to pbench-make-result-tb.
    result_dir=$(basename ${dir})
    if [[ -n "${user}" ]]; then
	user_arg="--user ${user}"
    else
	user_arg=""
    fi
    if [[ -n "${prefix}" ]]; then
	prefix_arg="--prefix ${prefix}"
    else
	prefix_arg=""
    fi
    result_tb_name=$(pbench-make-result-tb --result-dir "${result_dir}" --target-dir "${tmp}/${controller}" ${user_arg} ${prefix_arg} --xz-single-threaded "${xz_single_threaded}")
    if [[ ${?} -ne 0 ]]; then
	# Messaging already handled by pbench-make-result-tb
	continue
    fi
    if [[ -z "${result_tb_name}" ]]; then
	# Messaging already handled by pbench-make-result-tb
	continue
    fi
    pbench-copy-result-tb ${result_tb_name} ${results_repo} ${results_path_prefix}
    sts=${?}
    rm ${result_tb_name} ${result_tb_name}.md5.check
    if [[ ${?} -ne 0 ]]; then
	error_log "UNEXPECTED ERROR: rm failed to remove ${result_tb_name} and its .md5.check file"
	exit 1
    fi
    if [[ ${sts} -ne 0 ]]; then
	let failures=failures+1
	continue
    fi

    if [[ "$script_name" == "pbench-move-results" ]]; then
	rm -r ${result_dir}
	if [[ ${?} -ne 0 ]]; then
	    error_log "UNEXPECTED ERROR: rm failed to remove the ${result_dir} directory hierarchy"
	    exit 1
	fi
    else
	touch ${result_dir}.copied
	if [[ ${?} -ne 0 ]]; then
	    error_log "UNEXPECTED ERROR: touch failed to ${result_dir}.copied"
	    exit 1
	fi
    fi
    let runs_copied=runs_copied+1
done < ${tmp}/results.lis

let anything=runs_copied+failures
if [[ $anything -gt 0 ]]; then
    if [[ "$script_name" == "pbench-move-results" ]]; then
	op="moved"
    else
	op="copied"
    fi
    debug_log "successfully $op $runs_copied runs, encountered $failures failures"
fi
exit $failures
