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

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, cache=router.cache)

        for link in links_conf:
            if len(link.linkDict) == 0:
		#pdb.set_trace()
                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)
