#!/bin/bash

usage() { 
    echo "Usage: $0 create|start|stop|destroy [-f config_file] [-r repo_root] [-c service_name]" 1>&2
    exit 1 
}

create() {
    service_name=$1
    config_file=$2
    repo_root=$3
    if ! lxc-info -n ${service_name}; then
        # create a container with a static ip address
        echo "Creating container: ${service_name}"
        SERVICE=$(jq --arg NAME ${service_name} '.[] | select(.name==$NAME)' ${config_file})
        echo $SERVICE
        ip=$(echo $SERVICE | jq -r '.ip_address')
        echo "dhcp-host=${service_name},${ip}" >> /etc/lxc/dnsmasq.conf
        service lxc-net restart

        lxc-create -t download -n ${service_name} -- --dist ubuntu --release xenial --arch amd64

        # copy flame clmc files into the root container
        echo "Copying files to rootfs"
        container_dir="/var/lib/lxc/"${service_name}"/rootfs"
        container_vagrant_dir=${container_dir}"/vagrant"
        mkdir -p ${container_vagrant_dir}
        cp -f ${repo_root}/reporc "${container_vagrant_dir}"
        cp -rf ${repo_root}/scripts ${container_vagrant_dir}
        cp -rf ${repo_root}/src ${container_vagrant_dir}

        # start the container
        echo "Starting: ${service_name}"        
        lxc-start -n ${service_name}
        echo "Waiting for container to start: ${service_name}"
        STARTED="0"        
        while [ "$STARTED" == "0" ]; do STARTED=$(lxc-info -n ${service_name} -i | wc -l); done; 

        # provision software into each container
        echo "Provisioning: ${service_name}"
        if [ ${service_name} == "clmc-service" ]
        then
            influxdb_url=$(echo $SERVICE | jq -r '.influxdb_url')
            database_name=$(echo $SERVICE | jq -r '.database_name')
            report_period=$(echo $SERVICE | jq -r '.report_period')
            cmd="/vagrant/scripts/clmc-service/install.sh ${influxdb_url} ${database_name} ${report_period}"
            lxc-attach -n ${service_name} -v REPO_ROOT="/vagrant" -- ${cmd}
        elif [ ${service_name} == "test-runner" ]
        then
            cmd=/vagrant/src/test/clmctest/services/pytest/install.sh
            lxc-attach -n ${service_name} -- ${cmd}
        else
            # get container parameters
            location=$(echo $SERVICE | jq -r '.location')
            sf_id=$(echo $SERVICE | jq -r '.sf_id')
            sf_id_instance=$(echo $SERVICE | jq -r '.sf_id_instance')
            sfc_id=$(echo $SERVICE | jq -r '.sfc_id')
            sfc_id_instance=$(echo $SERVICE | jq -r '.sfc_id_instance')
            sr_id=$(echo $SERVICE | jq -r '.sr_id')
            ipendpoint_id=$(echo $SERVICE | jq -r '.ipendpoint_id')
            influxdb_url=$(echo $SERVICE | jq -r '.influxdb_url')
            database_name=$(echo $SERVICE | jq -r '.database_name')

            # install service function specific software
            cmd=/vagrant/src/test/clmctest/services/${sf_id}/install.sh
            lxc-attach -n ${service_name} -v REPO_ROOT="/vagrant" -- ${cmd}

            # install telegraf
            cmd=/vagrant/scripts/clmc-agent/install.sh
            lxc-attach -n ${service_name} -v REPO_ROOT="/vagrant" -- ${cmd}

            # copy telegraf configuration templates
            cp -f ${repo_root}/scripts/clmc-agent/telegraf.conf ${container_dir}/etc/telegraf/
            cp -f ${repo_root}/scripts/clmc-agent/telegraf_output.conf ${container_dir}/etc/telegraf/telegraf.d/
            cp ${repo_root}/src/test/clmctest/services/${sf_id}/telegraf_${sf_id}.conf ${container_dir}/etc/telegraf/telegraf.d/

            # replace telegraf template with container parameters
            # @todo do we really need both scripts to do this?
            cmd=/vagrant/scripts/clmc-agent/configure_template.sh
            lxc-attach -n ${service_name} -- ${cmd}
            cmd="/vagrant/scripts/clmc-agent/configure.sh ${location} ${sfc_id} ${sfc_id_instance} ${sf_id} ${sf_id_instance} ${ipendpoint_id} ${sr_id} ${influxdb_url} ${database_name}"
            lxc-attach -n ${service_name} -- ${cmd}

            # start telegraf
            lxc-attach -n ${service_name} -- service telegraf restart
        fi
    fi
}

start() {
    service_name=$1 
    if lxc-info -n ${service_name}; then
        echo "Starting container: ${service_name}"
        lxc-start -n ${service_name}
    fi
}

stop() {
    service_name=$1  
    if lxc-info -n ${service_name}; then
        echo "Stopping container: ${service_name}"
        lxc-stop -n ${service_name}
    fi
}

destroy() {
    service_name=$1
    config_file=$2
    if lxc-info -n ${service_name}; then
        echo "Stopping container: ${service_name}"
        lxc-stop -n ${service_name}
        echo "Destroying container: ${service_name}"
        lxc-destroy -n ${service_name}
        ip=$(jq -r --arg NAME ${service_name} '.[] | select(.name==$NAME) | .ip_address' ${config_file})
        sed -i "/dhcp-host=${service_name},/d" /etc/lxc/dnsmasq.conf
    fi    
}

# inc option index by 1 as first argument is the command and not parsed by getopts
if [ $# -gt 1 ]; then
    OPTIND=$((OPTIND+1))
fi

repo_root="/vagrant"
config_file="rspec.json"

# collect the optional arguments
while getopts "hf:r:c:" opt; do
  case $opt in
    h) usage; exit ;;
    f) config_file=${OPTARG} ;;
    r) repo_root=${OPTARG} ;;        
    c) container=${OPTARG} ;;
    \?) usage ;;
  esac
done

# check configuration file exists
if [ ! -f ${config_file} ]; then
    echo "Configuration file does not exist: ${config_file}" >&2
    usage
    exit 1
fi

# check repo root directory exists
if [ ! -d ${repo_root} ]; then
    echo "Repo root directory does not exist: ${repo_root}" >&2
    usage
    exit 1
fi

# iterate of list of services in configuration file 
command=$1
service_names=$(jq -r '.[].name' ${config_file})
for service_name in $service_names; do
    # if all or specific container
    if [ -z ${container} ] || [ ${container} == ${service_name} ]; then
        case "${command}" in
            create)
                create ${service_name} ${config_file} ${repo_root}
                ;;
            start)
                start ${service_name} ${config_file} ${repo_root}
                ;;
            stop)
                stop ${service_name} ${config_file} ${repo_root} 
                ;;
            destroy)
                destroy ${service_name} ${config_file} ${repo_root} 
                ;;
            *)
                usage
                ;;
        esac
    fi
done
