#!/usr/bin/env bash

##
# Copyright 2020 ATOS
#
# All Rights Reserved.
#
#   Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
#   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.
##

cat /dev/zero | ssh-keygen -q -N "" > /dev/null

install_osmclient(){
    echo -e "\nInstalling osmclient ${OSMCLIENT}"
    python3 -m pip install git+https://osm.etsi.org/gerrit/osm/osmclient@${OSMCLIENT}
}

download_packages(){
    echo -e "\nDownloading packages ${PACKAGES}"
    rm -rf ${PACKAGES_FOLDER}
    git clone https://osm.etsi.org/gitlab/vnf-onboarding/osm-packages.git ${PACKAGES_FOLDER}
}

download_tst010(){
    # Fetch conformance tests
    git clone --single-branch --branch ${NFV_TESTS_BRANCH} https://forge.etsi.org/rep/nfv/api-tests.git /robot-systest/conformance-tests/repo
    #python3 -m pip install -r /robot-systest/conformance-tests/repo/requirements.txt
    python3 -m pip install -r /robot-systest/conformance-tests/requirements.txt
}


create_k8scluster(){
    attempts=3
    while [ $attempts -ge 0 ] ; do
        echo -e "\n$( date '+%F_%H:%M:%S' ) Creating K8s Cluster"

        osm k8scluster-add --creds ${K8S_CREDENTIALS} --version "v1" --vim ${VIM_TARGET} --k8s-nets "{\"net1\": \"${VIM_MGMT_NET}\"}" ${VIM_TARGET} --description "Robot cluster"

        STATUS=""
        i=0
        while [[ ${STATUS} != "ENABLED" ]]
        do
            ((i++))
            if [[ $i -eq 5 ]]; then
                echo "K8s cluster stuck for more than 50 seconds:"
                osm k8scluster-show ${VIM_TARGET}
                osm k8scluster-delete ${VIM_TARGET}
                sleep 5
                break
            fi
            sleep 10
            STATUS=`osm k8scluster-list | grep ${VIM_TARGET} | awk '{print $8}'`
        done
        if [[ ${STATUS} = "ENABLED" ]] ; then
            break
        fi
        ((attempts--))
    done
    if [ $attempts -lt 0 ] ; then
        echo "K8s cluster failed to enter ENABLED state"
        exit 1
    fi
}

create_vim(){
    attempts=3
    while [ $attempts -ge 0 ] ; do
        echo -e "\n$( date '+%F_%H:%M:%S' ) Creating VIM ${VIM_TARGET}"
        osm vim-create --name ${VIM_TARGET} --user ${OS_USERNAME} --password ${OS_PASSWORD} --tenant ${OS_PROJECT_NAME} \
                       --auth_url ${OS_AUTH_URL} --account_type openstack --description vim \
                       --config "{management_network_name: ${VIM_MGMT_NET}, dataplane_physical_net: ${DATAPLANE:-physnet2}}" || true
        STATUS=""
        i=0
        while [[ ${STATUS} != "ENABLED" ]]
        do
            ((i++))
            if [[ $i -eq 5 ]]; then
                echo "VIM stuck for more than 50 seconds as: ${VIM_LIST}"
                osm vim-delete --force ${VIM_TARGET}
                sleep 5
                break
            fi
            sleep 10
            VIM_LIST=`osm vim-list --long | grep ${VIM_TARGET}`
            echo VIM status: ${VIM_LIST}
            STATUS=`echo ${VIM_LIST} | grep -io ENABLED`
        done
        if [[ ${STATUS} = "ENABLED" ]] ; then
            break
        fi
        ((attempts--))
    done
    if [ $attempts -lt 0 ] ; then
        echo "VIM failed to enter ENABLED state"
        exit 1
    fi
    if [ -n "${SDNC_URL}" ]; then
        osm sdnc-create --name sdnc-osm --type ${SDNC_TYPE} --user ${SDNC_USER} --password ${SDNC_PASSWORD} --url ${SDNC_URL}
        COUNTER=0
        STATUS=""
        while [ ${COUNTER} -lt 5 ] ; do
            echo "Checking status of SDNC sdnc-osm to see if it is enabled"
            STATUS=$(osm sdnc-show sdnc-osm |grep -io ENABLED)
            if [ "${STATUS}" == "ENABLED" ]; then
                break
            fi
            ((COUNTER++))
            sleep 10
        done
        if [ "${STATUS}" == "ENABLED" ]; then
            echo "SDNC enabled"
        else
            echo "SDNC failed to enter ENABLED state"
            osm sdnc-show sdnc-osm
            exit 1
        fi
        if [ -f /root/port-mapping.yaml ]; then
            osm vim-update ${VIM_TARGET} --sdn_controller sdnc-osm --sdn_port_mapping /root/port-mapping.yaml
            COUNTER2=0
            RESULT=""
            while [ ${COUNTER2} -lt 5 ] ; do
                echo "Checking status of VIM $VIM_TARGET to see if there is port-mapping"
                osm vim-show $VIM_TARGET |grep sdn-port-mapping
                if [ $? -eq 0 ]; then
                    RESULT="OK"
                    break
                fi
                ((COUNTER2++))
                sleep 10
            done
            if [ "${RESULT}" == "OK" ]; then
                echo "Port-mapping correctly added"
            else
                echo "Port-mapping failed to be added"
                osm vim-show ${VIM_TARGET}
                exit 1
            fi
        fi
    fi
}


PARAMS=""
RUN_CONFORMANCE_TESTS=false

while (( "$#" )); do
    case "$1" in
        -t|--testingtags)
            TEST=$2
            shift 2
            ;;
        -p|--packagesbranch)
            PACKAGES=$2 && download_packages
            shift 2
            ;;
        -o|--osmclientversion)
            OSMCLIENT=$2 && install_osmclient
            shift 2
            ;;
        -c|--createvim)
            create_vim
            create_k8scluster
            shift 1
            ;;
        -T)
            NFV_TESTS_BRANCH=$2 && download_tst010
            RUN_CONFORMANCE_TESTS=true
            shift 1
            ;;
        -h|--help)
            echo "OSM TESTS TOOL

Usage:
        docker run --rm=true -t osmtests --env-file <env_file> \\
            -v <path_to_reports>:/reports osmtests \\
            -v <path_to_clouds.yaml>:/robot-systest/clouds.yaml \\
            -v <path_to_kubeconfig>:/root/.kube/config \\
            -o <osmclient_version> \\
            -p <package_branch> \\
            -t <testing_tags>

Options:
        --env-file: It is the environmental file where is described the OSM target and VIM
        -o <osmclient_version> [OPTIONAL]: It is used to specify a particular osmclient version. Default: latest
        -p <package_branch> [OPTIONAL]: OSM packages repository branch. Default: master
        -t <testing_tags> [OPTIONAL]: Robot tests tags. [sanity, daily, regression, particular_test]. Default: sanity
        -T <testing_branch> [OPTIONAL]: Run SOL005 Robot conformance tests
        -c To create a VIM and K8s cluster for the tests

Volumes:
        <path_to_reports> [OPTIONAL]: It is the absolute path to reports location in the host
        <path_to_clouds.yaml> [OPTIONAL]: It is the absolute path to the clouds.yaml file in the host
        <path_to_kubeconfig> [OPTIONAL]: It is the kubeconfig file to be used for k8s clusters"

            exit 0
            ;;
        -*|--*=)
            echo "Error: Unsupported flag $1" >&2
            exit 1
            ;;
        *)
            PARAMS="$PARAMS $1"
            shift
            ;;
    esac
done

eval set -- "$PARAMS"

if [[ -n "$BRANCH_NAME" ]]; then
    PACKAGES=$BRANCH_NAME && download_packages
    OSMCLIENT=$BRANCH_NAME && install_osmclient
fi


if [ "$RUN_CONFORMANCE_TESTS" = true ] ; then
    python3 ${ROBOT_DEVOPS_FOLDER}/conformance-tests/run_conformance_tests.py
fi

if [[ -n "${TEST}" ]]; then
    robot -d ${ROBOT_DEVOPS_FOLDER}/reports -i ${TEST} ${ROBOT_DEVOPS_FOLDER}/testsuite/
else
    echo "No test was provided. Exiting..."
fi

exit 0
