#!/usr/bin/env python
"""
@package oft

OpenFlow test framework top level script

This script is the entry point for running OpenFlow tests
using the OFT framework.

The global configuration is passed around in a dictionary
ygenerally called config.  The keys have the following
significance.

    platform          : String identifying the target platform
    controller_host   : Host on which test controller is running (for sockets)
    controller_port   : Port on which test controller listens for switch cxn
    port_count        : (Optional) Number of ports in dataplane
    base_of_port      : (Optional) Base OpenFlow port number in dataplane
    base_if_index     : (Optional) Base OS network interface for dataplane
    test_spec         : (TBD) Specification of test(s) to run
    log_file          : Filename for test logging
    debug             : String giving debug level (info, warning, error...)
    dbg_level         : logging module value of debug level
    port_map          : Map of dataplane OpenFlow port to OS interface names

See config_defaults below for the default values.

To add configuration to the system, first add an entry to config_default
below.  If you want this to be a command line parameter, edit config_setup
to add the option and default value to the parser.  Then edit config_get
to make sure the option value gets copied into the configuration 
structure (which then gets passed to everyone else).

By convention, oft attempts to import the contents of a file by the 
name of $platform.py into the local namespace.  

IMPORTANT: That file should define a function platform_config_update which
takes a configuration dictionary as an argument and updates it for the
current run.  In particular, it should set up config["port_map"] with
the proper map from OF port numbers to OF interface names.

You can add your own platform, say gp104, by adding a file gp104.py
that defines the function platform_config_update and then use the
parameter --platform=gp104 on the command line.

If platform_config_update does not set config["port_map"], an attempt
is made to generate a default map via the function default_port_map_setup.
This will use "local" and "remote" for platform names if available
and generate a sequential map based on the values of base_of_port and
base_if_index in the configuration structure.

@todo Determine and implement conventions for test_spec.

The current model for test sets is basic.py.  The current convention is
that the test set should implement a function test_set_init which takes
an oft configuration dictionary and returns a unittest.TestSuite object.
Future test sets should do the same thing.

"""

import sys
from optparse import OptionParser
import logging
import unittest

# Import test files
import basic

##@var DEBUG_LEVELS
# Map from strings to debugging levels
DEBUG_LEVELS = {
    'debug'              : logging.DEBUG,
    'verbose'            : logging.DEBUG,
    'info'               : logging.INFO,
    'warning'            : logging.WARNING,
    'warn'               : logging.WARNING,
    'error'              : logging.ERROR,
    'critical'           : logging.CRITICAL
}

_debug_default = "warning"
_debug_level_default = DEBUG_LEVELS[_debug_default]

##@var config_default
# The default configuration dictionary for OFT
config_default = {
    "platform"           : "local",
    "controller_host"    : "127.0.0.1",
    "controller_port"    : 6633,
    "port_count"         : 4,
    "base_of_port"       : 1,
    "base_if_index"      : 1,
    "test_spec"          : "basic",
    "log_file"           : "oft.log",
    "debug"              : _debug_default,
    "dbg_level"          : _debug_level_default,
    "port_map"           : {}
}

# Map options to config structure
def config_get(opts):
    "Convert options class to OFT configuration dictionary"
    cfg = config_default.copy()
    cfg["platform"] = opts.platform
    cfg["controller_host"] = opts.controller_host
    cfg["controller_port"] = opts.controller_port
    cfg["test_spec"] = opts.test_spec
    cfg["log_file"] = opts.log_file
    if opts.debug not in DEBUG_LEVELS.keys():
        print "Warning:  Bad value specified for debug level; using default"
        opts.debug = _debug_default
    cfg["debug"] = opts.debug
    cfg["dbg_level"] = DEBUG_LEVELS[cfg["debug"]]
    cfg["base_of_port"] = opts.base_of_port
    cfg["base_if_index"] = opts.base_if_index
    cfg["port_count"] = opts.port_count
    return cfg

def config_setup(cfg_dflt):
    """
    Set up the configuration including parsing the arguments

    @param cfg_dflt The default configuration dictionary
    @return A pair (config, args) where config is an config
    object and args is any additional arguments from the command line
    """

    parser = OptionParser(version="%prog 0.1")

    # Set up default values
    parser.set_defaults(platform=cfg_dflt["platform"])
    parser.set_defaults(controller_host=cfg_dflt["controller_host"])
    parser.set_defaults(controller_port=cfg_dflt["controller_port"])
    parser.set_defaults(test_spec=cfg_dflt["test_spec"])
    parser.set_defaults(log_file=cfg_dflt["log_file"])
    parser.set_defaults(debug=cfg_dflt["debug"])
    parser.set_defaults(base_of_port=cfg_dflt["base_of_port"])
    parser.set_defaults(base_if_index=cfg_dflt["base_if_index"])
    parser.set_defaults(port_count=cfg_dflt["port_count"])

    plat_help = """Set the platform type.  Valid values include:
        local:  User space virtual ethernet pair setup
        remote:  Remote embedded Broadcom based switch
        """
    parser.add_option("-P", "--platform", help=plat_help)
    parser.add_option("-H", "--host", dest="controller_host",
                      help="The IP/name of the test controller host")
    parser.add_option("-p", "--port", dest="controller_port",
                      type="int", help="Port number of the test controller")
    parser.add_option("--test-spec", "--test-list", 
                      help="Indicate tests to run (TBD)")
    parser.add_option("--log-file", 
                      help="Name of log file, empty string to log to console")
    parser.add_option("--debug",
                      help="Debug lvl: debug, info, warning, error, critical")
    parser.add_option("--port_count",
                      help="Number of ports to use (optional)")
    parser.add_option("--base_of_port",
                      help="Base OpenFlow port number (optional)")
    parser.add_option("--base_if_index",
                      help="Base interface index number (optional)")
    # Might need this if other parsers want command line
    # parser.allow_interspersed_args = False
    (options, args) = parser.parse_args()

    config = config_get(options)

    return (config, args)

def logging_setup(config):
    """
    Set up logging based on config
    """
    _format = "%(asctime)s  %(name)-10s: %(levelname)-8s: %(message)s"
    _datefmt = "%H:%M:%S"
    if config["log_file"]:
        logging.basicConfig(filename=config["log_file"],
                            level=config["dbg_level"],
                            format=_format, datefmt=_datefmt)
    #@todo Handle "no log file"

def default_port_map_setup(config):
    """
    Setup the OF port mapping based on config
    @param config The OFT configuration structure
    @return Port map dictionary
    """
    if (config["base_of_port"] is None) or not config["port_count"]:
        return None
    port_map = {}
    if config["platform"] == "local":
        # For local, use every other veth port
        for idx in range(config["port_count"]):
            port_map[config["base_of_port"] + idx] = "veth" + \
                str(config["base_if_index"] + (2 * idx))
    elif config["platform"] == "remote":
        # For remote, use eth ports
        for idx in range(config["port_count"]):
            port_map[config["base_of_port"] + idx] = "eth" + \
                str(config["base_if_index"] + idx)
    else:
        return None

    logging.info("Built default port map")
    return port_map

#
# Main script
#

# Get configuration, set up logging, import platform from file
(config, args) = config_setup(config_default)
logging_setup(config)
logging.info("*** STARTING TEST RUN ***")

of_os_port_map = None
if config["platform"]:
    _imp_string = "from " + config["platform"] + " import *"
    logging.info("Importing: " + _imp_string)
    try:
        exec(_imp_string)
    except:
        logging.warn("Failed to import " + config["platform"] + " file")

try:
    platform_config_update(config)
except:
    logging.warn("Could not run platform host configuration")

if not config["port_map"]:
    # Try to set up default port mapping if not done by platform
    config["port_map"] = default_port_map_setup(config)

if not config["port_map"]:
    logging.critical("Interface port map is not defined.  Exiting")
    print("Interface port map is not defined.  Exiting")
    sys.exit(1)

logging.debug("Configuration: " + str(config))
logging.info("OF port map: " + str(config["port_map"]))

# Init the test sets
#@todo Use test-spec from config to determine which tests to run
basic_suite = basic.test_set_init(config)
if config["dbg_level"] >= logging.WARNING: _verb = 1
else: _verb = 2

unittest.TextTestRunner(verbosity=_verb).run(basic_suite)

logging.info("*** END OF TESTS ***")

