#!/usr/bin/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.node import CPULimitedCCNHost, CCNHost
from mininet.link import TCLink
from mininet.conf_parser import parse_hosts,parse_routers, parse_links
import os.path, time
import optparse
import datetime

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

    testbed = False
    parser = optparse.OptionParser(usage)

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

    (options, arg) = parser.parse_args()

    testbed = options.testbed

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

    return file, testbed


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

        hosts_conf = parse_hosts(conf_arq)
#       routers_conf = parse_routers(conf_arq)
        links_conf = parse_links(conf_arq)


        self.isTCLink = False
        self.isLimited = False

        for host in hosts_conf:
#	    print host
            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 router in routers_conf:
#            if router.cpu != None and self.isLimited != True:
#                self.isLimited = True
#            self.addHost(router.name,fib=router.uri_tuples,cpu=router.cpu,cores=router.cores)

        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='miniccnx.conf', testbed=False):
    "Create a network based on template_file"

    if template_file == '':
        template_file='miniccnx.conf'

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

    topo = CCNTopo(template_file)

    t = datetime.datetime.now()

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

    t2 = datetime.datetime.now()

    delta = t2 - t

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

    net.start()

    if testbed == True:
        info('Starting OSPFN ...\n')
        for host in net.hosts:
            host.cmd("cd {0}".format(host.name))
            host.cmd("./routing.sh {0}".format(host.name))

        time.sleep(60)

        for host in net.hosts:
            host.cmd("./ospfn-start.sh {0}".format(host.name))

        info('OSPFN configuration completed!\n')

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

    CLI(net)
    net.stop()

if __name__ == '__main__':

    template, testbed = parse_args()
    setLogLevel('info')
    execute(template, testbed)
