#!/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.util import ipStr, ipParse

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
from ndn.conf_parser import parse_hosts, parse_links

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"

    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()

    # Giving proper IPs to intf so neighbor nodes can communicate
    # This is one way of giving connectivity, another way could be
    # to insert a switch between each pair of neighbors
    ndnNetBase = "1.0.0.0"
    interfaces = []
    for host in net.hosts:
        for intf in host.intfList():
            link = intf.link
            node1, node2 = link.intf1.node, link.intf2.node
            if link.intf1 not in interfaces and link.intf2 not in interfaces:
                interfaces.append(link.intf1)
                interfaces.append(link.intf2)
                node1.setIP(ipStr(ipParse(ndnNetBase) + 1) + '/30', intf=link.intf1)
                node2.setIP(ipStr(ipParse(ndnNetBase) + 2) + '/30', intf=link.intf2)
                ndnNetBase = ipStr(ipParse(ndnNetBase) + 4)

    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)
        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)
