#!/usr/bin/env bash
#
# cisco-saf
#
# This file contains functions that is used by devstack plugins.sh when
# cisco-saf is enabled.
#

# Save trace setting
SAF_XTRACE=$(set +o | grep xtrace)
set +o xtrace

#
# Default settings
#
ENABLER_DCNM_USER=${ENABLER_DCNM_USER:-root}
ENABLER_DCNM_AMQP_USER=${ENABLER_DCNM_AMQP_USER:-admin}
ENABLER_SEG_ID_MIN=${ENABLER_SEG_ID_MIN:-10000}
ENABLER_SEG_ID_MAX=${ENABLER_SEG_ID_MAX:-20000}
ENABLER_LOG_LEVEL=${ENABLER_LOG_LEVEL:-WARNING}
ENABLER_LOG_DIR=${ENABLER_LOG_DIR:-~/Logs}
ENABLER_LOG_FILE=${ENABLER_LOG_FILE:-fabric_enabler.log}
ENABLER_DB_NAME=${ENABLER_DB_NAME:-cisco_dfa}
ENABLER_MYSQL_USER=${ENABLER_MYSQL_USER:-dfa}
ENABLER_MYSQL_HOST=${MYSQL_HOST}
ENABLER_DB_PASSWORD=${MYSQL_PASSWORD}
ENABLER_DCNM_DHCP=${ENABLER_DCNM_DHCP:-False}
NETWORKING_CISCO_ETC_SAF_DIR="etc/saf"
ENABLER_FABRIC_TYPE=${FABRIC_TYPE:-evpn}
ENABLER_FIREWALL_IN_IP_START=${FIREWALL_IN_IP_START:-100.121.10.0/24}
ENABLER_FIREWALL_IN_IP_END=${FIREWALL_IN_IP_END:-100.121.200.0/24}
ENABLER_FIREWALL_OUT_IP_START=${FIREWALL_OUT_IP_START:-200.121.10.0/24}
ENABLER_FIREWALL_OUT_IP_END=${FIREWALL_OUT_IP_END:-200.121.200.0/24}
ENABLER_FIREWALL_DUMMY_SUBNET=${FIREWALL_DUMMY_SUBNET:-9.9.9.0/24}

ENABLER_FIREWALL_HOST_NETWORK_PROFILE_EVPN_DYNAMIC=${FIREWALL_HOST_NETWORK_PROFILE_EVPN_DYNAMIC:-'serviceNetworkDynamicRoutingESChainLBESEvpnProfile'}
ENABLER_FIREWALL_HOST_NETWORK_PROFILE_EVPN_STATIC=${FIREWALL_HOST_NETWORK_PROFILE_EVPN_STATIC:-'serviceNetworkEvpnProfile'}
ENABLER_FIREWALL_HOST_NETWORK_PROFILE_DFA_DYNAMIC=${FIREWALL_HOST_NETWORK_PROFILE_DFA_DYNAMIC:-'serviceNetworkUniversalDynamicRoutingESProfile'}
ENABLER_FIREWALL_HOST_NETWORK_PROFILE_DFA_STATIC=${FIREWALL_HOST_NETWORK_PROFILE_DFA_STATIC:-'serviceNetworkUniversalTfStaticRoutingProfile'}

ENABLER_FIREWALL_EXT_PART_VRF_PROFILE_EVPN_DYNAMIC=${FIREWALL_EXT_PART_VRF_PROFILE_EVPN_DYNAMIC:-'vrf-common-evpn-external-dynamic-ES'}
ENABLER_FIREWALL_EXT_PART_VRF_PROFILE_EVPN_STATIC=${FIREWALL_EXT_PART_VRF_PROFILE_EVPN_STATIC:-'vrf-common-universal-external-static'}
ENABLER_FIREWALL_EXT_PART_VRF_PROFILE_DFA_DYNAMIC=${FIREWALL_EXT_PART_VRF_PROFILE_DFA_DYNAMIC:-'vrf-common-universal-external-dynamic-ES'}
ENABLER_FIREWALL_EXT_PART_VRF_PROFILE_DFA_STATIC=${FIREWALL_EXT_PART_VRF_PROFILE_DFA_STATIC:-'vrf-common-universal-external-static'}

ENABLER_FIREWALL_EXT_NETWORK_PROFILE_EVPN_DYNAMIC=${FIREWALL_EXT_NETWORK_PROFILE_EVPN_DYNAMIC:-'externalNetworkDynamicRoutingESEvpnProfile'}
ENABLER_FIREWALL_EXT_NETWORK_PROFILE_EVPN_STATIC=${FIREWALL_EXT_NETWORK_PROFILE_EVPN_STATIC:-'externalNetworkESEvpnProfile'}
ENABLER_FIREWALL_EXT_NETWORK_PROFILE_DFA_DYNAMIC=${FIREWALL_EXT_NETWORK_PROFILE_DFA_DYNAMIC:-'externalNetworkUniversalDynamicRoutingESProfile'}
ENABLER_FIREWALL_EXT_NETWORK_PROFILE_DFA_STATIC=${FIREWALL_EXT_NETWORK_PROFILE_DFA_STATIC:-'externalNetworkUniversalTfStaticRoutingESProfile'}

# Setup configuration parameters in enabler_conf.ini
function setup_saf_config {
    CFG_DIR=$1/${NETWORKING_CISCO_ETC_SAF_DIR}
    local cfgfile=${CFG_DIR}/enabler_conf.ini

    # DCNM settings
    iniset $cfgfile dcnm dcnm_ip $ENABLER_DCNM_IP_ADDR
    iniset $cfgfile dcnm dcnm_user $ENABLER_DCNM_USER
    iniset $cfgfile dcnm dcnm_amqp_user $ENABLER_DCNM_AMQP_USER
    iniset $cfgfile dcnm dcnm_password $ENABLER_DCNM_PASSWORD
    iniset $cfgfile dcnm segmentation_id_min $ENABLER_SEG_ID_MIN
    iniset $cfgfile dcnm segmentation_id_max $ENABLER_SEG_ID_MAX
    iniset $cfgfile dcnm dcnm_dhcp $ENABLER_DCNM_DHCP

    # RPC setting
    iniset $cfgfile dfa_rpc transport_url "rabbit://${RABBIT_USERID}:${RABBIT_PASSWORD}@${SERVICE_HOST}:5672//"

    # MySQL setting
    iniset $cfgfile dfa_mysql connection mysql://$ENABLER_MYSQL_USER:$ENABLER_DB_PASSWORD@$ENABLER_MYSQL_HOST/$ENABLER_DB_NAME?charset=utf8

    # Log setting
    iniset $cfgfile dfa_log log_dir $ENABLER_LOG_DIR
    iniset $cfgfile dfa_log log_file $ENABLER_LOG_FILE
    iniset $cfgfile dfa_log log_level $ENABLER_LOG_LEVEL

    FW_DEV=`echo $FIREWALL_DEVICE | awk -F ',' '{print $1}'`
    if [[ $FW_DEV != '' ]]; then
        iniset $cfgfile firewall device "[$FIREWALL_DEVICE]"
        iniset $cfgfile firewall fw_mgmt_ip $FIREWALL_MGMT_IP
        if [[ $FW_DEV != 'native' ]]; then
            iniset $cfgfile firewall fw_username $FIREWALL_USERNAME
            iniset $cfgfile firewall fw_password $FIREWALL_PASSWORD
            iniset $cfgfile firewall fw_interface_in $FIREWALL_INTERFACE_IN
            iniset $cfgfile firewall fw_interface_out $FIREWALL_INTERFACE_OUT
        fi
        iniset $cfgfile firewall fw_service_in_ip_start $ENABLER_FIREWALL_IN_IP_START
        iniset $cfgfile firewall fw_service_in_ip_end $ENABLER_FIREWALL_IN_IP_END
        iniset $cfgfile firewall fw_service_out_ip_start $ENABLER_FIREWALL_OUT_IP_START
        iniset $cfgfile firewall fw_service_out_ip_end $ENABLER_FIREWALL_OUT_IP_END
        iniset $cfgfile firewall fw_service_dummy_ip_subnet $ENABLER_FIREWALL_DUMMY_SUBNET
        if [[ $ENABLER_FABRIC_TYPE == 'evpn' ]]; then
            if [[ $FW_DEV == 'phy_asa' ]]; then
                iniset $cfgfile firewall fw_service_host_profile $ENABLER_FIREWALL_HOST_NETWORK_PROFILE_EVPN_DYNAMIC
                iniset $cfgfile firewall fw_service_part_vrf_profile $ENABLER_FIREWALL_EXT_PART_VRF_PROFILE_EVPN_DYNAMIC
                iniset $cfgfile firewall fw_service_ext_profile $ENABLER_FIREWALL_EXT_NETWORK_PROFILE_EVPN_DYNAMIC
            elif [[ $FW_DEV == 'native' ]]; then
                iniset $cfgfile firewall fw_service_host_profile $ENABLER_FIREWALL_HOST_NETWORK_PROFILE_EVPN_STATIC
                iniset $cfgfile firewall fw_service_part_vrf_profile $ENABLER_FIREWALL_EXT_PART_VRF_PROFILE_EVPN_STATIC
                iniset $cfgfile firewall fw_service_ext_profile $ENABLER_FIREWALL_EXT_NETWORK_PROFILE_EVPN_STATIC
            fi
        elif [[ $FABRIC_TYPE == 'dfa' ]]; then
            if [[ $FW_DEV == 'phy_asa' ]]; then
                iniset $cfgfile firewall fw_service_host_profile $ENABLER_FIREWALL_HOST_NETWORK_PROFILE_DFA_DYNAMIC
                iniset $cfgfile firewall fw_service_part_vrf_profile $ENABLER_FIREWALL_EXT_PART_VRF_PROFILE_DFA_DYNAMIC
                iniset $cfgfile firewall fw_service_ext_profile $ENABLER_FIREWALL_EXT_NETWORK_PROFILE_DFA_DYNAMIC
            elif [[ $FW_DEV == 'native' ]]; then
                iniset $cfgfile firewall fw_service_host_profile $ENABLER_FIREWALL_HOST_NETWORK_PROFILE_DFA_STATIC
                iniset $cfgfile firewall fw_service_part_vrf_profile $ENABLER_FIREWALL_EXT_PART_VRF_PROFILE_DFA_STATIC
                iniset $cfgfile firewall fw_service_ext_profile $ENABLER_FIREWALL_EXT_NETWORK_PROFILE_DFA_STATIC
            fi
        fi
    fi
}


# Install packages in the saf/requirements.txt
function install_saf_requirements {
    SAF_DIR=$1/networking_cisco/apps/saf

    if [[ -e $SAF_DIR/requirements.txt ]]; then
        echo "Installing packages from ${SAF_DIR}/requirements.txt"
        sudo -E pip install -r $SAF_DIR/requirements.txt
    else
        echo "Requirement file ${SAF_DIR}/requirements.txt does not exist."
        exit 1
    fi
}


# Create database for cisco-saf
function _config_database {

    mysqluser=$(mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -e "SELECT EXISTS(SELECT DISTINCT user FROM mysql.user WHERE user='$ENABLER_MYSQL_USER' AND host='$ENABLER_MYSQL_HOST')as user;")

    echo "Create ${ENABLER_DB_NAME} database."
    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -e "CREATE DATABASE IF NOT EXISTS ${ENABLER_DB_NAME} CHARACTER SET utf8;"

    val=(`echo $mysqluser | tr -d 'user '`)
    if [[ $val == 0 ]]; then
        # Mysql user does not exist. Create new one and set permission.
        echo "Creating user ${ENABLER_MYSQL_USER} for ${ENABLER_DB_NAME}."
        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -e "CREATE USER '$ENABLER_MYSQL_USER'@'$ENABLER_MYSQL_HOST' IDENTIFIED BY '$ENABLER_DB_PASSWORD';"
        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h127.0.0.1 -e "GRANT ALL PRIVILEGES ON *.* TO '$ENABLER_MYSQL_USER'@'$ENABLER_MYSQL_HOST';"
    fi
}

# Copy the enabler ini file
function _copy_fabric_enabler_config_file {
    sudo mkdir -p /etc/saf
    sudo cp $1/enabler_conf.ini /etc/saf
}


# Copy the upstart files
function _copy_fabric_enabler_upstart_files {
    if is_ubuntu; then
        if is_service_enabled q-svc; then
            sudo cp $1/fabric-enabler-server.conf /etc/init/
        fi
        if is_service_enabled q-agt; then
            sudo cp $1/fabric-enabler-agent.conf /etc/init/
        fi
    elif is_fedora; then
        if is_service_enabled q-svc; then
            sudo cp $1/fabric-enabler-server.service /usr/lib/systemd/system/
            sudo systemctl enable fabric-enabler-server.service
        fi
        if is_service_enabled q-agt; then
            sudo cp $1/fabric-enabler-agent.service /usr/lib/systemd/system/
            sudo systemctl enable fabric-enabler-agent.service
        fi
    else
        exit_distro_not_supported "list of packages"
    fi
}

# Start fabric enabler processes
function _start_fabric_enabler_processes {
    if is_ubuntu; then
        if is_service_enabled q-svc; then
            sudo start fabric-enabler-server
        fi
        if is_service_enabled q-agt; then
            sudo start fabric-enabler-agent
        fi
    elif is_fedora; then
        if is_service_enabled q-svc; then
            sudo systemctl start fabric-enabler-server.service
        fi
        if is_service_enabled q-agt; then
            sudo systemctl start fabric-enabler-agent.service
        fi
    else
        exit_distro_not_supported "list of packages"
    fi
}

# Stop fabric enabler processes
function _stop_fabric_enabler_processes {
    if is_ubuntu; then
        if is_service_enabled q-svc; then
            sudo stop fabric-enabler-server
        fi
        if is_service_enabled q-agt; then
            sudo stop fabric-enabler-agent
        fi
    elif is_fedora; then
        if is_service_enabled q-svc; then
            sudo systemctl stop fabric-enabler-server.service
        fi
        if is_service_enabled q-agt; then
            sudo systemctl stop fabric-enabler-agent.service
        fi
    else
        exit_distro_not_supported "list of packages"
    fi
}


# Set the configuration parameters in neutron, nova and keystone that
# are needed for cisco-saf service.
function configure_cisco_saf {
    SAF_INIT_DIR=$1/${NETWORKING_CISCO_ETC_SAF_DIR}/init
    ETC_SAF_DIR=$1/${NETWORKING_CISCO_ETC_SAF_DIR}

    # Create database for cisco-saf
    if is_service_enabled mysql; then
        _config_database
    fi

    # Copy the upstart files
    _copy_fabric_enabler_upstart_files ${SAF_INIT_DIR}

    # Copy config file
    _copy_fabric_enabler_config_file ${ETC_SAF_DIR}
}


# Start fabric enabler processes.
function start_cisco_saf_processes {
    _start_fabric_enabler_processes
}


# Stop fabric enabler processes.
function stop_cisco_saf_processes {
    _stop_fabric_enabler_processes
}


# Clean up cisco-saf service
function cleanup_cisco_saf_service {
    # Stop processes
    stop_cisco_saf_processes

    # Remove configurations

    # Clean up installation
}

# Restore trace setting
$SAF_XTRACE
