#!/bin/bash

# (C) Copyright Canonical 2011,2012

# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.

# This library 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 the GNU
# Lesser General Public License for more details.

# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

usage() {
    echo "Usage: lxc-wait --name=NAME --state=STATE"
}

help() {
    usage
    echo
    echo "lxc-wait waits for NAME container state to reach STATE"
    echo
    echo "Options :"
    echo "   -n, --name=NAME   NAME for name of the container"
    echo "   -s, --state=STATE ORed states to wait for"
    echo "                     STOPPED, STARTING, RUNNING, STOPPING,"
    echo "                     ABORTING, FREEZING, FROZEN"
}

set -e

valid_states=("STOPPED" "STARTING" "RUNNING" "STOPPING"
"ABORTING" "FREEZING" "FROZEN" "THAWED" "MAX_STATE")

container_exists() {
    local c=$1
    local list=`lxc-ls -1`
    local name

    for name in $list; do
        if [ "$c" = "$name" ]; then
            echo "yes"
        fi
        echo "no"
    done
}

verify_state() {
    local s="$1"
    local i

    for((i=0;i<${#valid_states[@]};i++)); do
        if [ "$s" = "${valid_states[$i]}" ]; then
            echo "ok"; return;
        fi
    done
    echo "bad"; return;
}
        
badstate=""
verify_states() {
    local states=$1
    local s
    local v

    for s in $states; do
        echo "verifying $s"
        v=$(verify_state "$s")
        if [ $v = "bad" ]; then
            echo "bad";
            badstate="$s"
            return;
        fi
    done
    echo "ok";
}

state_is_in() {
    local state=$1
    local states=$2
    local s

    for s in $states; do
        if [ "$state" = "$s" ]; then
            echo "yes"; return;
        fi
    done
    echo "no"
}

shortoptions='hn:s:'
longoptions='help,name:,states:'

getopt=$(getopt -o $shortoptions --longoptions  $longoptions -- "$@")
if [ $? != 0 ]; then
    usage
    exit 1;
fi

eval set -- "$getopt"

states="RUNNING"

while true; do
    case "$1" in
    -h|--help)
        help
        exit 1
        ;;
    -n|--name)
        shift
        lxc_name=$1
        shift
        ;;
    -s|--states)
        shift
        states=$1
        shift
        ;;
    --)
        shift
        break;;
    *)
        echo $1
        usage
        exit 1
        ;;
    esac
done

if [ -z "$lxc_name" ]; then
    echo "no container name specified"
    usage
    exit 1
fi

if [ "$(id -u)" != "0" ]; then
   echo "This command has to be run as root"
   exit 1
fi

type lxc-info > /dev/null || { echo "lxc-info not found."; exit 1; }

v=$(container_exists $lxc_name)
if [ "$v" = "no" ]; then
    echo "Container $lxc_name does not exist"
    exit 1
fi
states2="`echo $states | sed -e 's/|/ /g'`"
v=$(verify_states "${states2}")
if [ "$v" = "bad" ]; then
   echo "invalid state $badstate in provided set"
   exit 1
fi
	

while [ 1 ]; do
    o=`lxc-info -s -n $lxc_name`
    s=`echo $o | awk '{ print $2 }'`
    if [ $(state_is_in "$s" "${states2}") = "yes" ]; then
        break;
    fi
    sleep 1
done

exit 0
