#!/usr/bin/env python

from mininet.topo import Topo
from mininet.net import Mininet
from mininet.log import setLogLevel, output, info
from mininet.cli import CLI
from mininet.link import TCLink
from mininet.conf_parser import parse_hosts, parse_links

from ndn.experiments.multiple_failure_experiment import MultipleFailureExperiment
from ndn.experiments.pingall_experiment import PingallExperiment
from ndn.experiments.failure_experiment import FailureExperiment
from ndn.ndn_host import NdnHost, CpuLimitedNdnHost

import os.path, time
import optparse
import datetime
from os.path import expanduser

from ndn.nlsr import Nlsr, NlsrConfigGenerator
from ndn.nfd import Nfd

def parse_args():
    usage="""Usage: minindn [template_file] [ -t | --testbed ]
    If no template_file is given, will try to load template
    from file minindn.conf in the current directory.
    If --testbed is used, minindn will run the NDN Project Testbed.
    This assumes you are in the testbed directory in the minindn installation
    directory.
    """

    testbed = False
    pingall = False
    hr = False
    failure = False
    isMultipleFailure = False

    parser = optparse.OptionParser(usage)

    parser.add_option("-t", "--testbed", action="store_true", dest="testbed",
    help="instantiates NDN Testbed")

    parser.add_option("--pingall", action="store", dest="pingall", type="int",
    help="Sequentiall pings all the other nodes from each node")

    parser.add_option("--ctime", action="store", dest="ctime", type="int",
    help="Specify convergence time for the topology (Default 60 seconds)")

    parser.add_option("--hr", action="store_true", dest="hr",
    help="--hr is used to turn on hyperbolic routing")

    parser.add_option("--faces", action="store", dest="faces", type="int",
    help="Specify number of faces 0-60")

    parser.add_option("--failure", action="store_true", dest="failure",
    help="Run failure experiment, specify the number of pings using pingall")

    parser.add_option("--multiple-failure", action="store_true", dest="isMultipleFailure",
    help="Run multiple failure experiment; each node will fail and recover once")

    parser.add_option("--no-cli", action="store_false", dest="isCliEnabled",
        help="Run experiments and exit without showing the command line interface")

    (options, arg) = parser.parse_args()

    testbed = options.testbed
    pingall = options.pingall
    ctime = options.ctime
    hr = options.hr
    faces = options.faces
    failure = options.failure
    isMultipleFailure = options.isMultipleFailure
    isCliEnabled = options.isCliEnabled

    if ctime is None:
        ctime = 60

    if isCliEnabled is None:
        isCliEnabled = True

    if len(arg) == 0 or len(arg) > 2:
        file = ''
    else:
        file = arg[0]

    return file, testbed, pingall, ctime, hr, faces, failure, isMultipleFailure, isCliEnabled

class NdnTopo(Topo):
    def __init__(self, conf_arq, **opts):
        Topo.__init__(self, **opts)

        global hosts_conf
        global links_conf
        hosts_conf = parse_hosts(conf_arq)
        links_conf = parse_links(conf_arq)

        self.isTCLink = False
        self.isLimited = False

        for host in hosts_conf:
            if host.cpu != None and self.isLimited != True:
                self.isLimited = True
            self.addHost(host.name, app=host.app, fib=host.uri_tuples,cpu=host.cpu,cores=host.cores,cache=host.cache)

        for link in links_conf:
            if len(link.linkDict) == 0:
                self.addLink(link.h1, link.h2)
            else:
                self.addLink(link.h1, link.h2, **link.linkDict)
                self.isTCLink = True

        info('Parse of ' + conf_arq + ' done.\n')

def execute(template_file='minindn.conf', testbed=False, pingall=None, ctime=None, hr=False, faces=3, failure=False, isMultipleFailure=False, isCliEnabled=True):
    "Create a network based on template_file"

    home = expanduser("~")

    if template_file == '':
        template_file='minindn.conf'

    if os.path.exists(template_file) == False:
        info('No template file given and default template file minindn.conf not found. Exiting...\n')
        quit()

    topo = NdnTopo(template_file)

    t = datetime.datetime.now()

    if topo.isTCLink == True and topo.isLimited == True:
        net = Mininet(topo,host=CpuLimitedNdnHost,link=TCLink)
    elif topo.isTCLink == True and topo.isLimited == False:
        net = Mininet(topo,host=NdnHost,link=TCLink)
    elif topo.isTCLink == False and topo.isLimited == True:
        net = Mininet(topo,host=CpuLimitedNdnHost)
    else:
        net = Mininet(topo,host=NdnHost)

    t2 = datetime.datetime.now()

    delta = t2 - t

    info('Setup time: ' + str(delta.seconds) + '\n')

    net.start()

    nodes = ""    # Used later to check prefix name in checkFIB

    # NLSR initialization
    for host in net.hosts:
        nodes += str(host.name) + ","

        conf = next(x for x in hosts_conf if x.name == host.name)
        host.nlsrParameters = conf.nlsrParameters

        if faces is not None:
            host.nlsrParameters["max-faces-per-prefix"] = faces

        if hr is True:
            host.nlsrParameters["hyperbolic-state"] = "on"

        # Generate NLSR configuration file
        configGenerator = NlsrConfigGenerator(host, home)
        configGenerator.createConfigFile()

        # Start NLSR
        host.nlsr = Nlsr(host)
        host.nlsr.start()

    nodes = nodes[0:-1]

    if isMultipleFailure is True:
        test = MultipleFailureExperiment(net, nodes, ctime, Nfd.STRATEGY_BEST_ROUTE_V3)
        test.start()
    elif failure is True:
        test = FailureExperiment(net, nodes, ctime, Nfd.STRATEGY_BEST_ROUTE_V3)
        test.start()
    elif pingall is not None:
        test = PingallExperiment(net, nodes, ctime, pingall, Nfd.STRATEGY_BEST_ROUTE_V3)
        test.start()

    for host in net.hosts:
        if 'app' in host.params:
            if host.params['app'] != '_':
                host.cmd(host.params['app'])

    if isCliEnabled is True:
        CLI(net)

    net.stop()

if __name__ == '__main__':
    hosts_conf = []
    links_conf = []
    template, testbed, pingall, ctime, hr, faces, failure, isMultipleFailure, isCliEnabled = parse_args()

    setLogLevel('info')
    execute(template, testbed, pingall, ctime, hr, faces, failure, isMultipleFailure, isCliEnabled)
