#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib"
urequire DEFAULTS ipcalc

if [ $# -eq 1 -a "$1" == "--help" ]; then
    exit_with uecho "$scriptname: Faire une connexion ssh en utilisant l'exécutable approprié au réseau source et destination

USAGE
    $scriptname [user@]host"
fi

# fonctions de support
function match_network() {
    local ip="$1" network="$2"
    local -a includes excludes domains
    local spec
    array_copy includes "${network}_INCLUDES"
    array_copy excludes "${network}_EXCLUDES"
    array_copy domains "${network}_DOMAINS"

    if ipcalc_checkip "$ip" >/dev/null; then
        for spec in "${excludes[@]}"; do
            if ipcalc_match "$ip" "$spec"; then
                return 1
            fi
        done
        for spec in "${includes[@]}"; do
            if ipcalc_match "$ip" "$spec"; then
                return 0
            fi
        done
    else
        for spec in "${domains[@]}"; do
            [[ "$ip" == *."$spec" ]] && return 0
        done
    fi
    return 1
}

# paramètres de l'environnement
DO=
if [ "$1" == --debug ]; then
    # Activer le mode DEBUG
    shift
    set_verbosity -D
elif [ "$1" == --trace ]; then
    # Activer le mode DEBUG
    shift
    set_verbosity -D
    TRACE=1
    DO=qvals
fi

NETWORKS=()
RULES=()
set_defaults mssh

# déterminer d'où l'on vient
from=
array_from_lines myips "$(ip addr | awk '$1 == "inet" { gsub(/\/.*/, "", $2); print $2 }')"
for network in "${NETWORKS[@]}"; do
    for myip in "${myips[@]}"; do
        if match_network "$myip" "$network"; then
            from="$network"
            break
        fi
    done
    [ -n "$from" ] && break
done
edebug "FROM: ${from:-ANY} (${myips[*]})"

# analyser la ligne de commande
vars="$("$scriptdir/ussh" --parse "$@")" || exit 1

[ -n "$TRACE" ] && echo "$vars"
eval "$vars"

for userhost in "${hosts[@]}"; do
    # déterminer où l'on veut aller
    splituserhost "$userhost" user host

    to=
    for network in "${NETWORKS[@]}"; do
        if match_network "$host" "$network"; then
            to="$network"
            break
        fi
    done
    edebug "TO: ${to:-ANY} ($host)"

    # Sélectionner la commande ssh à utiliser
    found=
    for rule in "${RULES[@]}"; do
        splitfsep "$rule" : rfrom rule2
        splitfsep "$rule2" : rto rssh
        if [ \( -z "$rfrom" -o "$from" == "$rfrom" \) -a \
             \( -z "$rto"   -o "$to" == "$rto" \) ]; then
            found=1
            $DO ${exec:+exec} "$rssh" "${options[@]}" "$userhost" "${args[@]}"
            break
        fi
    done
    if [ -z "$found" ]; then
        $DO ${exec:+exec} "$ssh" "${options[@]}" "$userhost" "${args[@]}"
    fi
done
