#!/bin/bash
#/*
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements.  See the NOTICE file distributed with
# * this work for additional information regarding copyright ownership.
# * The OpenAirInterface Software Alliance licenses this file to You under
# * the OAI Public License, Version 1.1  (the "License"); you may not use this file
# * except in compliance with the License.
# * You may obtain a copy of the License at
# *
# *      http://www.openairinterface.org/?page_id=698
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *-------------------------------------------------------------------------------
# * For more information about the OpenAirInterface (OAI) Software Alliance:
# *      contact@openairinterface.org
# */


function top_usage {
    echo "OAI CI VM script"
    echo "   Original Author: Raphael Defosseux"
    echo "   Requirements:"
    echo "     -- uvtool uvtool-libvirt apt-cacher"
    echo "     -- $VM_OSREL image already synced"
    echo ""
    echo "Usage:"
    echo "------"
    echo "    oai-ci-vm-tool (-h|--help) { `for i in "${COMMANDS_NAME[@]}"; do echo -n $i,;done` ..." }
    echo ""
}

function variant_usage {

    for (( i=0 ; i<${#VARIANTS_LONG[@]} ; i++ )) 
    do        
    	unset BUILD_OPTIONS
    	unset VARIANT_INFO
    	check_set_variant "${VARIANTS_SHORT[$i]}"
        printf  "    --variant %-15s OR -%-3s" "${VARIANTS_LONG[$i]}" "${VARIANTS_SHORT[$i]}"
        if [ "$BUILD_OPTIONS" = "" ]
        then
        	echo -n "    ( test "
        else
        	echo -n "    ( build and test "
        fi
        echo "$VARIANT_INFO )"
        if [ "$1" = "full" ]
        then        
            printf  "               VM_NAME=%-15s          ARCHIVES_LOC=%-15s\n" "$VM_NAME" "$ARCHIVES_LOC"
            printf  "               VM_MEMORY=%-15s        VM_CPU=%-15s\n" "$VM_MEMORY" "$VM_CPU"       
            printf  "               NB_PATTERN_FILES=%-15s BUILD_OPTIONS=%-15s\n" "$NB_PATTERN_FILES" "\"$BUILD_OPTIONS\""
            printf  "               LOG_PATTERN=%-15s      EXPERIMENTAL=%-15s\n\n\n" "$LOG_PATTERN"  "$EXPERIMENTAL"
        fi
    done    
}

function command_options_usage {

    local -A HELP_MSG
    HELP_MSG["jn"]="    Specify the name of the Jenkins job."
    HELP_MSG["id"]="    Specify the build ID of the Jenkins job."
    HELP_MSG["ws"]="    Specify the workspace"
    HELP_MSG["var"]="    Specify the variant to build."
    HELP_MSG["k"]="    Keep the VM alive after the build."
    HELP_MSG["D"]="    Run as daemon"
    HELP_MSG["gu"]="    Specify the URL of the GIT Repository."
    HELP_MSG["pu"]="    trigger a push action from the Jenkins job to the specified url, \"--trigger pu\" can also be used"
    HELP_MSG["mr"]="    trigger a merge request action from the Jenkins job, \"--trigger mr\" can also be used"
    HELP_MSG["sb"]="    Specify the source branch of the merge request."
    HELP_MSG["sc"]="    Specify the source commit ID (SHA-1) of the merge request."
    HELP_MSG["tb"]="    Specify the target branch of the merge request (usually develop)."    
    HELP_MSG["tc"]="    Specify the target commit ID (SHA-1) of the merge request."
    HELP_MSG["br"]="    Specify the branch of the push event."
    HELP_MSG["co"]="    Specify the commit ID (SHA-1) of the push event."
    HELP_MSG["epc"]="    (two arguments) Specify the ip addresses of an external EPC, on respectively the core network and the UEs network"
    HELP_MSG["sim"]="   Specify the path to the sim file, used to emulate the oai UE sim card "
    for (( m=0 ; m<2 ; m++ ))
    do
      if [[ $m -eq 0  || ( $m > 0 && ${MANDATORY_OPTMASK[$m]} > 0 ) ]]
      then
        echo "Mandatory Options ($((m+1))):"
        echo "---------------------"    
        for (( i=0 ; i<${#SHORT_OPTIONS[@]} ; i++ )) 
        do  
    	  if [ $(( MANDATORY_OPTMASK[$m] & $(( 2**$i )) )) -ne 0 ]
    	  then
    	     if [ "${LONG_OPTIONS[$i]}" != "" ]
    	     then
    	       local ARGPATTERN
    	       if [[ !("${HELP_MSG[${SHORT_OPTIONS[$i]}]}" =~  "Specify") ]]
    	       then
    	       	   ARGPATTERN=""
    	       elif [[ "${HELP_MSG[${SHORT_OPTIONS[$i]}]}" =~  "(two arguments)" ]]
    	       then 
       	       	   ARGPATTERN="#### ####"
       	       else
       	       	   ARGPATTERN="####"
    	       fi
    	   	   printf "    %s %s OR "  "--${LONG_OPTIONS[$i]}" "$ARGPATTERN"
    	     fi
             printf "%s %s \n" "-${SHORT_OPTIONS[$i]}" "$ARGPATTERN"
             printf "  %s\n\n"  "${HELP_MSG[${SHORT_OPTIONS[$i]}]}"
          fi
        done
    fi
    done
    echo "Options:"
    echo "--------"

    for (( i=0 ; i<${#SHORT_OPTIONS[@]} ; i++ )) 
    do  
    	if [ $(( ALLOWED_OPTMASK & $(( 2**$i )) )) -ne 0 ]
    	then
    	   if [ "${LONG_OPTIONS[$i]}" != "" ]
    	   then
    	   	   printf "    %s #### OR "  "--${LONG_OPTIONS[$i]}"
    	   fi
           printf "%s #### \n" "-${SHORT_OPTIONS[$i]}"
           printf "  %s\n\n"  "${HELP_MSG[${SHORT_OPTIONS[$i]}]}"
        fi
    done 

    for (( i=0 ; i<${#SHORT_OPTIONS[@]} ; i++ )) 
    do  
    	if [ $(( ALLOWED_OPTMASK & $(( 2**$i )) )) -ne 0 ]
    	then
    	   if [ "$(type -t ${LONG_OPTIONS[$i]}_usage)" = 'function'  ]
    	   then
    	   	   ${LONG_OPTIONS[$i]}_usage
    	   fi
        fi
    done    
    echo "    --help OR -h"
    echo "    Print this help message."
    echo ""
}

# function to set specific behavior depending on the TESTPLATFORM_OWNER variable
# which may be set by a jenkins server for exemple
function platform_set {
	if [ "$TESTPLATFORM_OWNER" != "" ]
	then
	  echo "Running on $TESTPLATFORM_OWNER platform"
	  if [ -x "/usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh" ]
	  then
	    . /usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh
	  fi
	fi
}

function setvar_usage {
	declare -A HELP_VAR
	HELP_VAR["VM_OSREL"]="OS release to use in virtual machines"
	HELP_VAR["RUN_EXPERIMENTAL"]="Enforce execution of variants with EXPERIMENTAL variable set to \"true\"" 
    HELP_VAR["OPTIONAL_APTCACHER"]="build and Run tests will fail if apt-cacher not installed and this variable not set to \"true\""
    HELP_VAR["TESTPLATFORM_OWNER"]="Allow pipeline customization via execution of an externel scripts residing on the jenkins server" 
    echo "--setvar_<varname> <value> where varname is one of:"
	for i in ${AUTHORIZED_VAR[@]}; do printf "%20s :     %s\n" "$i" "${HELP_VAR[$i]}" ;done
}

# functions variant__v<n>__<variant name> are used to define build or test variants
# The only thing to do to define a new variant is to add a function which name
# match this template. Note that "_" character in function <varriant name> part
# will be replaced by "-" character in  build_variant_arrays function, this is
# for compatibility reasons  

function variant__v1__enb_usrp {
    NB_PATTERN_FILES=9
    BUILD_OPTIONS="--eNB -w USRP --mu"
}
    
function variant__v2__basic_sim {
    NB_PATTERN_FILES=13
    BUILD_OPTIONS="--eNB --UE"
    VM_MEMORY=8192
    RUN_OPTIONS="complex"
}

function variant__v3__phy_sim {
    NB_PATTERN_FILES=3
    BUILD_OPTIONS="--phy_simulators"
    RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
}

function variant__v4__cppcheck {
    VM_MEMORY=4096
    LOG_PATTERN=cppcheck.xml
    NB_PATTERN_FILES=1
    BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -I openair3/NAS/COMMON/UTIL -j4"
}

function variant__v7__enb_ethernet {
    VM_MEMORY=4096
    ARCHIVES_LOC=enb_eth
    NB_PATTERN_FILES=8
    BUILD_OPTIONS="--eNB"
}
function variant__v8__ue_ethernet {
    VM_MEMORY=4096
    ARCHIVES_LOC=ue_eth
    NB_PATTERN_FILES=12
    BUILD_OPTIONS="--UE"
}

function variant__v10__flexran_rtc {
    ARCHIVES_LOC=flexran
    NB_PATTERN_FILES=1
    BUILD_OPTIONS="cmake . && make -j2"
    VARIANT_INFO="non-OSA"
}
function variant__v20__l1_sim {
    ARCHIVES_LOC=l1_sim
    RUN_OPTIONS="complex"
    EXPERIMENTAL="true"
}
    
function variant__v21__rf_sim {
    RUN_OPTIONS="complex"
    EXPERIMENTAL="true"
}

function variant__v22__l2_sim {
    RUN_OPTIONS="complex"
}

# Following function lists all variant__v<n>__<variant name> functions
# and set the VARIANTS_SHORT and VARIANTS_LONG arrays from
# the function names
function build_variant_arrays {
    VARIANTS=`declare -F`
    VARIANTS=${VARIANTS//"declare -f "}
    for i in $VARIANTS
    do
    	if [ `expr match "$i" 'variant__v'` -eq 10 ]
    	then
    	   IDX1=`expr match "$i" 'variant__v[0-9]\+__'`
    	   VARIANTS_SHORT+=(${i:9:$((IDX1-11))})
    	   LONGNAME=${i:$IDX1}
           VARIANTS_LONG+=(${LONGNAME//"_"/"-"})
    	fi
    done
}

# check that the passed argument is a valid variant, set
# default values for variant related variables and then execute
# the corresponding variant__v<n>__<variant name> function
function check_set_variant {
    for (( i=0 ; i<${#VARIANTS_SHORT[@]} ; i++ )) 
    do  
    	if [ "$1" = "${VARIANTS_SHORT[$i]}" ] || [ "$1" = "${VARIANTS_LONG[$i]}" ]
    	then
            VM_NAME=ci-${VARIANTS_LONG[$i]}
            LOG_PATTERN=.$ASN1VER.txt
            ARCHIVES_LOC=${VARIANTS_LONG[$i]//"-"/"_"}  
            VM_MEMORY=2048
            VM_CPU=4
            EXPERIMENTAL=""
            NBARGS=$[$NBARGS+$VARIANT_OPTID]   
            variant__${VARIANTS_SHORT[$i]}__${VARIANTS_LONG[$i]//"-"/"_"}
            return 0
        fi
    done   
    echo "$1" is not a valid variant
    variant_usage
    exit 1
    
}

function check_command_options {
	GIVEN_OPTIONS=$1
	declare -a MANDATORY_OPTIONS=("${!2}")
	if [ ${MANDATORY_OPTIONS[1]} -eq 0 ]
	then
		MANDATORY_OPTIONS[1]=${MANDATORY_OPTIONS[0]}
	fi
	OPTIONAL_OPTIONS=$3
	if [ $(($GIVEN_OPTIONS & ${MANDATORY_OPTIONS[0]} )) -ne ${MANDATORY_OPTIONS[0]} ] && [ $(($GIVEN_OPTIONS & ${MANDATORY_OPTIONS[1]} )) -ne ${MANDATORY_OPTIONS[1]} ]
    then
        echo "Syntax Error: missing option(s) for $4 command"
        ${4//-/_}_usage
        exit 1
    fi	
    
    if [ $(( $(($GIVEN_OPTIONS ^ ${MANDATORY_OPTIONS[0]})) | $OPTIONAL_OPTIONS )) -ne  $(( $OPTIONAL_OPTIONS )) ] && [ $(( $(($GIVEN_OPTIONS ^ ${MANDATORY_OPTIONS[1]})) | $OPTIONAL_OPTIONS )) -ne  $(( $OPTIONAL_OPTIONS )) ]
    then
        echo "Syntax Error: unknown option(s) for $4 command"
        ${4//-/_}_usage
        exit 1
    fi	 
}

function check_ipv4addr {
    local  ipaddr=$1
    local  stat=1

    if [[ $ipaddr =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]
    then
        OIFS=$IFS
        IFS='.'
        ipaddr=($ipaddr)
        IFS=$OIFS
        [[ ${ipaddr[0]} -le 255 && ${ipaddr[1]} -le 255 \
            && ${ipaddr[2]} -le 255 && ${ipaddr[3]} -le 255 ]]
        stat=$?
    fi
    if [ $stat -ne 0 ]
    then
    	echo $ipaddr " is not a valid ip V4 address"
    	exit 1
    fi
}

function check_setvar {
    for i in ${AUTHORIZED_VAR[@]}
    do
    	if [ "$1" = "$i" ]
    	then
    	   echo "Setting $1 to $2..."
    	   export "$1"="$2"
    	   return 0
    	fi
    done
    echo " $1 is not a variable you can set"
    setvar_usage
    exit 1
}	

platform_set
MY_DIR=$(dirname $(readlink -f $0))
. $MY_DIR/createVM.sh
. $MY_DIR/buildOnVM.sh
. $MY_DIR/waitBuildOnVM.sh
. $MY_DIR/destroyAllRunningVM.sh
. $MY_DIR/runTestOnVM.sh
. $MY_DIR/reportBuildLocally.sh
. $MY_DIR/reportTestLocally.sh


if [ $# -lt 1 ]
then
    echo "Syntax Error: too few arguments"
    echo ""
    top_usage
    exit 1
fi

VM_TEMPLATE=ci-


# look for default ASN1 release in cmake directives
# It will be the release used when building
ASN1VEROPT=( `grep "add_list2_option(RRC_ASN1_VERSION" cmake_targets/CMakeLists.txt` )
ASN1VER=${ASN1VEROPT[1]//\"}
unset ASN1VEROPT

# variable to identify and store the command (build, create ...)
# command index in the COMMAND and COMMANDS_NAME arrays 
HELP_CMD=0
CREATE_CMD=1
BUILD_CMD=2
WAIT_CMD=3
DESTROY_CMD=4
TEST_CMD=5
REPORT_BUILD_CMD=6
REPORT_TEST_CMD=7

COMMANDS_NAME=(help create build wait destroy test report-build report-test)

#COMMAND will be used to save the command entered as argument
declare -A COMMAND
for i in "${COMMANDS_NAME[@]}"
do 
	COMMAND[$i]=0
done

# build the variant arrays
declare -a VARIANTS_SHORT
declare -a VARIANTS_LONG
build_variant_arrays

#variables to process options, for each option we define a variable to store
# its value and a bit mask, used to check allowed options depending on 
# the command

# The two following arrays must be consistent: a given index must point to the long and short options
# of a given command
SHORT_OPTIONS=( "jn" "id" "ws" "k" "D" "gu" "pu" "mr" "var" "notused" "sb" "sc" "tb" "tc" "br" "co" "epc" "sim")
LONG_OPTIONS=( "job-name" "build-id" "workspace" "keep-vm-alive" "daemon" "git-url" "push" "merge-request" 
               "variant" "notused" "src-branch" "src-commit" "target-branch" "target-commit" "branch" "commit" 
               "external-epc" "sim-file")

JOB_NAME=XX
JOB_NAME_OPTINDEX=0
JOB_NAME_OPTID=1

BUILD_ID=XX
BUILD_ID_OPTINDEX=1
BUILD_ID_OPTID=2

JENKINS_WKSP_OPTINDEX=2
JENKINS_WKSP_OPTID=4

KEEP_VM_ALIVE_OPTINDEX=3
KEEP_VM_ALIVE_OPTID=8
KEEP_VM_ALIVE=0

DAEMON_OPTINDEX=4
DAEMON_OPTID=$((2**4))
DAEMON=0

GITURL_OPTINDEX=5
GITURL_OPTID=$((2**5))

PU_OPTINDEX=6
PU_OPTID=$((2**6))
PU_TRIG=0

MR_OPTINDEX=7
MR_OPTID=$((2**7))
MR_TRIG=0

VARIANT_OPTINDEX=8
VARIANT_OPTID=$((2**8))

SB_OPTINDEX=10
SB_OPTID=$((2**10))

SC_OPTINDEX=11
SC_OPTID=$((2**11))

TB_OPTINDEX=12
TB_OPTID=$((2**12))

TC_OPTINDEX=13
TC_OPTID=$((2**13))

BR_OPTINDEX=14
BR_OPTID=$((2**14))

CO_OPTINDEX=15
CO_OPTID=$((2**15))

EPC_IPADDR_OPTINDEX=16
EPC_IPADDR_OPTID=$((2**16))
EPC_IPADDR=""

SIM_OPTINDEX=17
SIM_OPTID=$((2**17))
SIMFILE=""

RUN_OPTIONS="none"


# list of variables that can be set via the --setvar option
AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL OPTIONAL_APTCACHER TESTPLATFORM_OWNER")


#variables to set which OS VM should use
#if [ -f "/etc/os-release" ]
#then
#    source /etc/os-release
#    VM_OS="$NAME"
#    VM_OSREL="$VERSION_CODENAME"
#    VM_ARCHI=`uname -m`	
#else
    VM_OS="ubuntu"
    VM_OSREL="xenial"
    VM_ARCHI="x86_64"		
#fi


# variant option, ie the test variant which will be run triggers the
# variables listed below, used to configure the VM and to define what this
# VM will do. The variant can be specified by the --variant option or by a 
# -V<xx> option.
VM_NAME=""
VM_MEMORY=0
VM_CPU=0
ARCHIVES_LOC=""
LOG_PATTERN=""
NB_PATTERN_FILES=0
BUILD_OPTIONS=""
RUN_OPTIONS=""



# NARGS is used to check that only valid options are used for the given command
# It is a bit mask, each bit set to 1 specifies the corresponding option 
# has been entered on the command line. MANDATORY_OPTMASK and ALLOWED_OPTMASK define
# respectively the mandatory and optional parameters of the entered command
NBARGS=0
MANDATORY_OPTMASK=(0 0)   # some command have two sets of mandatory options
ALLOWED_OPTMASK=0

while [[ $# -gt 0 ]]
do
key="$1"

if [ "$(type -t $funcname)" != 'function' ]; then
    funcname=do_it_normal
fi
case $key in
    --debug)
    set -v
    set -x
    shift
    ;;
    -h|--help|help)
    COMMAND["help"]=1
    # following word might specify the topic for the help request
    # but help can also be used without argument, so don't shift
    if [ "$2" != "" ] && [ "$(type -t ${2//-/_}_usage)" = 'function' ]
    then
           HELPCMD="${2//-/_}_usage full"
    fi
    shift
    ;;
    create)
    COMMAND[$key]=1
    # For create, mandatory options: jn, id. Optional: variant
    MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID ))
    ALLOWED_OPTMASK=$(($VARIANT_OPTID))
    # It is implied to keep the VM when creating it
    KEEP_VM_ALIVE=1
    shift
    ;;
    build)
    COMMAND[$key]=1
    # For build, mandatory options: jn, id, ws. Optional: variant, k, D
    MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
    ALLOWED_OPTMASK=$(($KEEP_VM_ALIVE_OPTID + $DAEMON_OPTID + $VARIANT_OPTID))
    shift
    ;;
    wait)
    # For test, mandatory options: jn, id, ws. Optional: variant, k     	
    COMMAND[$key]=1
    MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID)) 
    ALLOWED_OPTMASK=$(($KEEP_VM_ALIVE_OPTID + $VARIANT_OPTID))  
    shift
    ;;
    test) 	
    COMMAND[$key]=1
    # For test, mandatory options: jn, id, ws. Optional: variant, k, epc 
    MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID)) 
    ALLOWED_OPTMASK=$(($KEEP_VM_ALIVE_OPTID + $VARIANT_OPTID + $EPC_IPADDR_OPTID + $SIM_OPTID))
    shift
    ;;
    destroy)
    COMMAND[$key]=1
    # For destroy, mandatory options: jn, id. 
    MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID))   
    shift
    ;;
    report-build)
    COMMAND[$key]=1
    # For report-build, mandatory options: jn, id, ws, gu, pu, br,co.
    #                                  or: jn, id, ws, gu, mr, sb, sc, tb, tc.
    MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID + $GITURL_OPTID + $PU_OPTID + $BR_OPTID + $CO_OPTID))
    MANDATORY_OPTMASK[1]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID + $GITURL_OPTID + $MR_OPTID + $SB_OPTID + $SC_OPTID)) 
    MANDATORY_OPTMASK[1]=$(( ${MANDATORY_OPTMASK[1]} + $TB_OPTID + $TC_OPTID))     
    shift
    ;;
    report-test) 
    COMMAND[$key]=1
    # For report-test, mandatory options: jn, id, ws, gu, pu, br,co.
    #                                 or: jn, id, ws, gu, mr, sb, sc, tb, tc.
    MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
    MANDATORY_OPTMASK[0]=$((${MANDATORY_OPTMASK[0]} + $GITURL_OPTID + $PU_OPTID + $BR_OPTID + $CO_OPTID))
    MANDATORY_OPTMASK[1]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
    MANDATORY_OPTMASK[1]=$((${MANDATORY_OPTMASK[1]} + GITURL_OPTID + $MR_OPTID + $SB_OPTID + $SC_OPTID))  
    MANDATORY_OPTMASK[1]=$((${MANDATORY_OPTMASK[1]} + $TB_OPTID + $TC_OPTID))   
    shift
    ;;
    -jn|--job-name)
    JOB_NAME="$2"
    NBARGS=$[$NBARGS+$JOB_NAME_OPTID]
    shift
    shift
    ;;
    -id|--build-id)
    BUILD_ID="$2"
    NBARGS=$[$NBARGS+$BUILD_ID_OPTID]
    shift
    shift
    ;;
    -ws|--workspace)
    JENKINS_WKSP="$2"
    NBARGS=$[$NBARGS+$JENKINS_WKSP_OPTID]
    shift
    shift
    ;;
    -k|--keep-vm-alive)
    KEEP_VM_ALIVE=1
    NBARGS=$[$NBARGS+$KEEP_VM_ALIVE_OPTID]
    shift
    ;;
    -D|--daemon)
    DAEMON=1
    NBARGS=$[$NBARGS+$DAEMON_OPTID]
    shift
    ;;
    -gu|--git-url)
    GIT_URL="$2"
    NBARGS=$[$NBARGS+$GITURL_OPTID]
    shift
    shift
    ;;
    --trigger)
    TRIG="$2"
    case $TRIG in
        merge-request)
        MR_TRIG=1
        NBARGS=$[$NBARGS+$MR_OPTID]       
        ;;
        push)
        PU_TRIG=1
        NBARGS=$[$NBARGS+$PU_OPTID]        
        ;;
        *)
        echo ""
        echo "Syntax Error: Invalid Trigger option -> $TRIG"
        echo ""
        trigger_usage
        exit
        ;;
    esac
    shift
    shift
    ;;
    -mr|--merge-request)
    MR_TRIG=1
    NBARGS=$[$NBARGS+$MR_OPTID]
    shift
    ;;
    -pu|--push)
    PU_TRIG=1
    NBARGS=$[$NBARGS+$PU_OPTID]
    shift
    ;;
    -sb|--src-branch)
    SOURCE_BRANCH="$2"
    NBARGS=$[$NBARGS+$SB_OPTID]
    shift
    shift
    ;;
    -sc|--src-commit)
    SOURCE_COMMIT_ID="$2"
    NBARGS=$[$NBARGS+$SC_OPTID]
    shift
    shift
    ;;
    -tb|--target-branch)
    TARGET_BRANCH="$2"
    NBARGS=$[$NBARGS+$TB_OPTID]
    shift
    shift
    ;;
    -tc|--target-commit)
    TARGET_COMMIT_ID="$2"
    NBARGS=$[$NBARGS+$TC_OPTID]
    shift
    shift
    ;;
    -br|--branch)
    SOURCE_BRANCH="$2"
    NBARGS=$[$NBARGS+$BR_OPTID]
    shift
    shift
    ;;
    -co|--commit)
    SOURCE_COMMIT_ID="$2"
    NBARGS=$[$NBARGS+$CO_OPTID]
    shift
    shift
    ;;
    -epc|--external-epc)
    check_ipv4addr "$2"
    check_ipv4addr "$3"
    EPC_IPADDR="$2"
    EPC_TUN_IPADDR="$3"
    NBARGS=$[$NBARGS+$EPC_IPADDR_OPTID]
    shift
    shift
    shift
    ;;
    -sim|--sim-file)
    SIMFILE="$2"
    NBARGS=$[$NBARGS+$SIM_OPTID]
    shift
    shift
    ;;   
    --setvar_*)
    check_setvar "${key:9}" "$2"
    shift
    shift
    ;;
    -v[0-9] | -v[0-9][0-9])
    check_set_variant ${key//"-"} 
    shift
    ;;
    -var|--variant)
    variant="$2" 
    check_set_variant ${2}
    shift
    shift
    ;;
    *)
    echo "Syntax Error: unknown option: $key"
    echo ""
    top_usage
    exit 1
esac
done

i=0
for (( COUNT=1 ; COUNT<${#COMMAND[@]} ; COUNT++ )) 
do    
   if [ ${COMMAND[${COMMANDS_NAME[$COUNT]}]} -eq 1 ]
   then
   	   COMMAND_KEY[$i]=${COMMANDS_NAME[$COUNT]} 
      (( i++ ))	   
   fi
done

if [ ${COMMAND["help"]} -eq 1 ]
then
    if [ ${#COMMAND_KEY[@]} -ne 1 ] && [ "$HELPCMD" == "" ]
    then 
       top_usage
    elif  [ "$HELPCMD" != "" ]
    then
       $HELPCMD
    else
       ${COMMAND_KEY[0]//-/_}_usage
    fi 
    exit 0
else
    if [ ${#COMMAND_KEY[@]} -gt 1 ]
    then
        echo "Syntax Error, too many commands:  ${COMMAND_KEY[@]}" 
        top_usage
        exit 1
    fi

    if [ -z "${COMMAND_KEY[0]}" ]
    then
        echo "Syntax Error: no command, specify one of: ${COMMANDS_NAME[@]}"
        top_usage
        exit 1
    fi

    check_command_options $NBARGS MANDATORY_OPTMASK[@] $ALLOWED_OPTMASK ${COMMAND_KEY[0]}
fi

if [ ${COMMAND[${COMMANDS_NAME[$REPORT_BUILD_CMD]}]} -ne 1 ]  && [ ${COMMAND[${COMMANDS_NAME[$REPORT_TEST_CMD]}]} -ne 1 ]
then
    # Checking uvt-kvm is installed
    UVT_KVM_PATH=`which uvt-kvm | grep -c uvt-kvm`
    if [ $UVT_KVM_PATH -eq 0 ]
    then
        echo "Error: uvt-kvm is not installed"
        top_usage
        exit 1
    fi
fi

if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ]
then
    VM_TEMPLATE=ci-
else
    VM_TEMPLATE=${JOB_NAME}-b${BUILD_ID}-
fi
# set default variant
if [ "$VM_NAME" = "" ]
then
	check_set_variant "v1"
fi
VM_NAME=`echo $VM_NAME | sed -e "s#ci-#$VM_TEMPLATE#"`
VM_CMDS=${VM_NAME}_cmds.txt
ARCHIVES_LOC=${JENKINS_WKSP}/archives/${ARCHIVES_LOC}

STATUS=0
if [ ${COMMAND[${COMMANDS_NAME[$CREATE_CMD]}]} -eq 1 ]
then
    if [[ "$BUILD_OPTIONS" = "" ]]
    then
        echo "$VM_NAME is not a build variant"
        exit 0
    else
        create_vm
    fi
fi
if [ ${COMMAND[${COMMANDS_NAME[$BUILD_CMD]}]} -eq 1 ]
then
    if [[  "$BUILD_OPTIONS" = "" ]]
    then
        echo " $VM_NAME is not a build variant"
        exit 0
    else
        build_on_vm
    fi
    if [ $DAEMON -eq 0 ] && [ $STATUS -eq 0 ]
    then
        check_on_vm_build
    fi
fi
if [ ${COMMAND[${COMMANDS_NAME[$WAIT_CMD]}]} -eq 1 ]
then
    if [[  "$BUILD_OPTIONS" = "" ]]
    then
        echo "$VM_NAME is not a build variant"
        exit 0
    else
        wait_on_vm_build
    fi
    if [ $STATUS -eq 0 ]
    then
        check_on_vm_build
    fi
fi
if [ ${COMMAND[${COMMANDS_NAME[$TEST_CMD]}]} -eq 1 ]
then
    # variant with EXPERIMENTAL variable set to true won't run and will be
    # considered OK, except if --setvar_RUN_EXPERIMENTAL option has been set to true
    if [ "$EXPERIMENTAL" = "true" ] && [ "$RUN_EXPERIMENTAL" != "true" ]
    then
        echo "Currently $VM_NAME Testing is not implemented / enabled"
        echo "remove EXPERIMENTAL variable definition from this variant"
        echo " or use option --setvar_RUN_EXPERIMENTAL=true to enforce testing it"
        echo "STATUS seems OK"
        exit $STATUS
    fi

    ARCHIVES_LOC=${ARCHIVES_LOC}/test
    run_test_on_vm
fi
if [ ${COMMAND[${COMMANDS_NAME[$DESTROY_CMD]}]} -eq 1 ]
then
    destroy_vm
fi
if [ ${COMMAND[${COMMANDS_NAME[$REPORT_BUILD_CMD]}]} -eq 1 ]
then
    report_build
fi
if [ ${COMMAND[${COMMANDS_NAME[$REPORT_TEST_CMD]}]} -eq 1 ]
then
    report_test
fi

# Did command pass or fail?
if [ $STATUS -eq 0 ]
then
    echo "STATUS seems OK"
else
    echo "STATUS failed?"
fi
exit $STATUS