# Neutron NEC OpenFlow plugin
# ---------------------------

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

# Configuration parameters
OFC_HOST=${OFC_HOST:-127.0.0.1}
OFC_PORT=${OFC_PORT:-8888}

OFC_API_HOST=${OFC_API_HOST:-$OFC_HOST}
OFC_API_PORT=${OFC_API_PORT:-$OFC_PORT}
OFC_OFP_HOST=${OFC_OFP_HOST:-$OFC_HOST}
OFC_OFP_PORT=${OFC_OFP_PORT:-6633}
OFC_DRIVER=${OFC_DRIVER:-trema}
OFC_RETRY_MAX=${OFC_RETRY_MAX:-0}
OFC_RETRY_INTERVAL=${OFC_RETRY_INTERVAL:-1}

# Main logic
# ---------------------------

source $TOP_DIR/lib/neutron_plugins/ovs_base

function neutron_plugin_create_nova_conf {
    _neutron_ovs_base_configure_nova_vif_driver
}

function neutron_plugin_install_agent_packages {
    # SKIP_OVS_INSTALL is useful when we want to use Open vSwitch whose
    # version is different from the version provided by the distribution.
    if [[ "$SKIP_OVS_INSTALL" = "True" ]]; then
        echo "You need to install Open vSwitch manually."
        return
    fi
    _neutron_ovs_base_install_agent_packages
}

function neutron_plugin_configure_common {
    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/nec
    Q_PLUGIN_CONF_FILENAME=nec.ini
    Q_DB_NAME="neutron_nec"
    Q_PLUGIN_CLASS="neutron.plugins.nec.nec_plugin.NECPluginV2"
}

function neutron_plugin_configure_debug_command {
    _neutron_ovs_base_configure_debug_command
}

function neutron_plugin_configure_dhcp_agent {
    :
}

function neutron_plugin_configure_l3_agent {
    _neutron_ovs_base_configure_l3_agent
}

function _quantum_plugin_setup_bridge {
    if [[ "$SKIP_OVS_BRIDGE_SETUP" = "True" ]]; then
        return
    fi
    # Set up integration bridge
    _neutron_ovs_base_setup_bridge $OVS_BRIDGE
    # Generate datapath ID from HOST_IP
    local dpid=$(printf "%07d%03d%03d%03d\n" ${HOST_IP//./ })
    sudo ovs-vsctl --no-wait set Bridge $OVS_BRIDGE other-config:datapath-id=$dpid
    sudo ovs-vsctl --no-wait set-fail-mode $OVS_BRIDGE secure
    sudo ovs-vsctl --no-wait set-controller $OVS_BRIDGE tcp:$OFC_OFP_HOST:$OFC_OFP_PORT
    if [ -n "$OVS_INTERFACE" ]; then
        sudo ovs-vsctl --no-wait -- --may-exist add-port $OVS_BRIDGE $OVS_INTERFACE
    fi
    _neutron_setup_ovs_tunnels $OVS_BRIDGE
}

function neutron_plugin_configure_plugin_agent {
    _quantum_plugin_setup_bridge

    AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-nec-agent"

    _neutron_ovs_base_configure_firewall_driver
}

function neutron_plugin_configure_service {
    iniset $NEUTRON_CONF DEFAULT api_extensions_path neutron/plugins/nec/extensions/
    iniset /$Q_PLUGIN_CONF_FILE ofc host $OFC_API_HOST
    iniset /$Q_PLUGIN_CONF_FILE ofc port $OFC_API_PORT
    iniset /$Q_PLUGIN_CONF_FILE ofc driver $OFC_DRIVER
    iniset /$Q_PLUGIN_CONF_FILE ofc api_retry_max OFC_RETRY_MAX
    iniset /$Q_PLUGIN_CONF_FILE ofc api_retry_interval OFC_RETRY_INTERVAL

    _neutron_ovs_base_configure_firewall_driver
}

function neutron_plugin_setup_interface_driver {
    local conf_file=$1
    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
    iniset $conf_file DEFAULT ovs_use_veth True
}

# Utility functions
# ---------------------------

# Setup OVS tunnel manually
function _neutron_setup_ovs_tunnels {
    local bridge=$1
    local id=0
    GRE_LOCAL_IP=${GRE_LOCAL_IP:-$HOST_IP}
    if [ -n "$GRE_REMOTE_IPS" ]; then
        for ip in ${GRE_REMOTE_IPS//:/ }; do
            if [[ "$ip" == "$GRE_LOCAL_IP" ]]; then
                continue
            fi
            sudo ovs-vsctl --no-wait add-port $bridge gre$id -- \
                set Interface gre$id type=gre options:remote_ip=$ip
            id=`expr $id + 1`
        done
    fi
}

function has_neutron_plugin_security_group {
    # 0 means True here
    return 0
}

function neutron_plugin_check_adv_test_requirements {
    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
}

# Restore xtrace
$NEC_XTRACE
