#!/bin/bash

#
# csc : Cluster SSH Command
# Launch command over SSH on cluster hosts with "dialog" DEBIAN_FRONTEND.
#

usage () {
    echo "Usage: csc [OPTION]... [COMMAND]"
    echo "  -h  show help"
    echo "  -v  enable verbose mode"
    echo "  -c  specify config dir, default is $HOME/.config/csc"
    echo "  -g  specify group"
	echo "  -d  enable dry run mode"
}

# variable defaults
usage=false
verbose=false
confdir="$HOME/.config/csc"
dryRun=false

# get options
while getopts "hvc:g:d" opt; do
    case $opt in
        h)
            usage=true
            ;;
        v)
            verbose=true
            ;;
        c)
            confdir=$OPTARG
            ;;
        g)
            group=$OPTARG
            ;;
		d)
			dryRun=true
			;;
        \?)
            echo "Invalid option: -$OPTARG" >&2
            exit 1
            ;;
        :)
            echo "Option -$OPTARG requires an argument." >&2
            exit 1
            ;;
    esac
done

# clean $@ of options
shift $((OPTIND-1))

cmd=$*

if [ "$usage" = true ]
then
    usage
    exit 0
fi

if [ "$verbose" = true ]
then
	echo "> starting csc"
	echo "> options :"
	echo "  - help: $usage"
	echo "  - verbose: $verbose"
	echo "  - confdir: $confdir"
	echo "  - group: $group"
	echo "  - dryRun: $dryRun"
fi

if [ -z "$cmd" ]
then
    echo "Error : command is missing"
    echo
    usage
    exit 1
fi

if [ -z "$group" ]
then
    echo "Error: group is not defined!"
    echo
    usage
    exit 1
fi

hosts="$confdir/$group"

if [ ! -f "$hosts" ]
then
    echo "Error: hosts file $confdir/$group does not exist!"
    echo
    usage
    exit 1
fi

# see http://askubuntu.com/questions/506158/unable-to-initialize-frontend-dialog-when-using-ssh
#FRONTEND="DEBIAN_FRONTEND=noninteractive" # then you should use clush instead :)
FRONTEND="TERM=$TERM DEBIAN_FRONTEND=dialog"
#FRONTEND="DEBIAN_FRONTEND=readline"

if [ "$verbose" = true ]
then
    echo "> will do :"
    echo "  grep -v '^ *#' \"$hosts\" | grep -v '^ *$' | while IFS= read -r line; do ssh -t \"\$line\" \"$FRONTEND $cmd\"; done"
fi

mapfile -t host_list < <(grep -v '^ *#' "$hosts" | grep -v '^ *$')
total=${#host_list[@]}

for i in "${!host_list[@]}"; do
    line="${host_list[$i]}"
    n=$((i + 1))

    if [ "$dryRun" = true ]; then
        prefix="\e[33m[DRY RUN]\e[0m "
    else
        prefix=""
    fi

    echo -e "${prefix}\e[34m[$n/$total]\e[0m \e[32m\"$cmd\"\e[0m \e[34mon\e[0m \e[32m$line\e[0m  \e[34m→\e[0m  \e[33mssh -t \"$line\" \"$FRONTEND $cmd\"\e[0m"

    if [ "$dryRun" = false ]; then
        ssh -t "$line" "$FRONTEND $cmd"
        rc=$?
        if [ $rc -eq 0 ]; then
            echo -e "\e[32m✓ ok\e[0m"
        else
            echo -e "\e[31m✗ failed (exit $rc)\e[0m"
        fi
    fi
done

if [ "$verbose" = true ]
then
    echo "> All done, bye."
fi

exit 0
