#!/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 import ExperimentManager
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
import sys

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

def printExperimentNames():
    experimentNames = ExperimentManager.getExperimentNames()

    print "Mini-NDN experiments:"
    for experiment in experimentNames:
        print "  %s" % experiment

def parse_args():
    usage="""Usage: minindn [template_file] [ -t | --testbed ]
    If no template_file is given, ndn_utils/default-topology.conf (given sample file)
    will be used.
    If --testbed is used, minindn will run the NDN Project Testbed.
    """

    testbed = False
    hr = False

    parser = optparse.OptionParser(usage)

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

    parser.add_option("--experiment", action="store", dest="experiment",
    help="Runs the specified experiment")

    parser.add_option("--list-experiments", action="store_true", dest="shouldListExperiments",
    help="Lists the names of all available experiments")

    parser.add_option("--nPings", action="store", dest="nPings", type="int",
    help="Number of pings to perform between each node in the experiment")

    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("--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
    experimentName = options.experiment
    shouldListExperiments = options.shouldListExperiments
    nPings = options.nPings
    ctime = options.ctime
    hr = options.hr
    faces = options.faces
    isCliEnabled = options.isCliEnabled

    if shouldListExperiments is not None:
        printExperimentNames()
        sys.exit()

    if ctime is None:
        ctime = 60

    if nPings is None:
        nPings = 300

    if isCliEnabled is None:
        isCliEnabled = True

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

    return file, testbed, experimentName, nPings, ctime, hr, faces, 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, experimentName=None, nPings=None, ctime=None, hr=False, faces=3, isCliEnabled=True):
    "Create a network based on template_file"

    install_dir='/usr/local/etc/mini-ndn/'

    if template_file == '':
        template_file = install_dir + 'default-topology.conf'

    if testbed:
        template_file = install_dir + 'minindn.testbed.conf'

    if os.path.exists(template_file) == False:
        info('No template file given and default template file cannot be 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]

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

    # Load experiment
    if experimentName is not None:
        print "Loading experiment: %s" % experimentName

        experimentArgs = {
            "net": net,
            "nodes": nodes,
            "ctime": ctime,
            "nPings": nPings,
            "strategy": Nfd.STRATEGY_BEST_ROUTE_V3
        }

        experiment = ExperimentManager.create(experimentName, experimentArgs)

        if experiment is not None:
            experiment.start()
        else:
            print "ERROR: Experiment '%s' does not exist" % experimentName
            return

    if isCliEnabled is True:
        CLI(net)

    net.stop()

if __name__ == '__main__':

    hosts_conf = []
    links_conf = []
    template, testbed, experimentName, nPings, ctime, hr, faces, isCliEnabled = parse_args()

    setLogLevel('info')
    execute(template, testbed, experimentName, nPings, ctime, hr, faces, isCliEnabled)
