#!/bin/sh
# This program is free software: you can redistribute it and/or modify it
# under the terms of the the GNU General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
# PURPOSE.  See the applicable version of the GNU General Public
# License for more details.
#.
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2012 Canonical, Ltd.

export LC_ALL=C

usage() {
cat <<EOF
usage: $0 [OPTIONS]

Copies ACTIVE network manager connection into device

OPTIONS:
  -h	Show this message
  -s    Specify the serial of the device to install (see adb $ADBOPTS devices)
  -n    Select network file
  -t    Timeout for waiting on network connection to become active.
        Default=$WAIT_TIMEOUT

  --skip-setup   Skip setting up a network-manager connection on the target.
  --skip-wait    Skip waiting for the network connection to become active.

EOF
}

ADBOPTS=""
OPTION_NETWORK_FILE=""
SKIP_SETUP=""
SKIP_WAIT=""
WAIT_TIMEOUT="80s"

ARGS=$(getopt -o n:s:t:h -l "help,skip-setup,skip-wait,timeout:" -n "$0" -- "$@")
if [ $? -ne 0 ] ; then
    exit 1
fi
eval set -- "$ARGS"

while true; do
    case "$1" in
        -h|--help)
            usage
            exit 0
            ;;
        -n)
            shift;
	    OPTION_NETWORK_FILE=$1
            shift;
            ;;
	-s)
            shift;
            ADBOPTS="-s $1"
            shift;
            ;;
	-t|--timeout)
            shift;
            WAIT_TIMEOUT=$1
            shift;
            ;;
	--skip-wait)
            shift;
	    SKIP_WAIT=1
            ;;
	--skip-setup)
            shift;
	    SKIP_SETUP=1
            ;;
        --)
            shift;
            break;
            ;;
    esac
done

NETWORK_MANAGER=/etc/NetworkManager/system-connections

find_active_network() {
    wireless_adapter="$(nmcli -t -f device,type dev | egrep wireless | cut -d: -f1)"
    if [ -z "$wireless_adapter" ]
    then
        echo "No wireless adapter found, exiting"
        exit 1
    fi
   network_active_uuid="$(nmcli -t -f name,uuid,devices,vpn con status | grep $wireless_adapter | egrep ':no$'| cut -d: -f2)"
    if [ -z "$network_active_uuid" ]
    then
        echo "No active wifi network connection, exiting"
        exit 1
    fi
    network_file=$(sudo grep -H "$network_active_uuid" /etc/NetworkManager/system-connections/* | grep uuid | cut -f1 -d:)

    echo "$network_file"
}

setup_connection() {
    if [ -z "$OPTION_NETWORK_FILE" ]; then
        network_file=$(find_active_network)
    else
        network_file=$OPTION_NETWORK_FILE
    fi

    if [ ! -f "$network_file" ]
    then
        echo "Network connection file \"$network_file\" cannot be read"
        exit 1
    fi

    echo Network file is $network_file

    TMP_FILE=$(mktemp)
    CMD="grep -v mac-address"
    [ ! -r "$network_file" ] && CMD="sudo $CMD"
    $CMD "$network_file" > $TMP_FILE

    echo Provisioning network file to device
    target_network_file=$NETWORK_MANAGER/active_ws_connection.conf
    adb $ADBOPTS push $TMP_FILE $target_network_file
    adb $ADBOPTS shell "chmod 600 $target_network_file"

    rm -f $TMP_FILE

    echo
    echo Network setup complete
}

wait_for_network() {
    timeout $WAIT_TIMEOUT sh <<EOF
        while true ; do
	    # adb shell doesn't return errors from the command
	    # also, ping can be blocked like it is in the QA lab. however,
	    # the logic below will ensure that DNS resolution part of the
	    # ping worked, which should be enough to prove to us that the
	    # network stack is ready
            if adb $ADBOPTS shell ping -c1 launchpad.net | grep PING ; then
                exit 0
            fi
            done
EOF
    if [ $? -ne 0 ] ; then
        echo "Network connection failed to become active."
	exit 1
    fi
}

# Quick way to make sure that we fail gracefully if more than one device 
# is connected and no serial is passed
err="$(adb $ADBOPTS wait-for-device 2>&1)"
if [ "$err" = "error: more than one device and emulator" ]; then
    echo "$err"
    adb devices
    exit 1
fi

[ -n "$SKIP_SETUP" ] || setup_connection
[ -n "$SKIP_WAIT" ] || wait_for_network
