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

def parse_args():
    usage="""Usage: miniccnx [template_file]
    If no template_file is given, will try to load template 
    from file miniccnx.conf in the current directory.
    """

    parser = optparse.OptionParser(usage)

    _, arg = parser.parse_args()
    
    if len(arg) != 1:
        arg = ''
    else:
        arg = arg[0]
    
    return arg


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:
            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)
            
        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)
            
        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'):
    "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()

    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 = parse_args()
    setLogLevel('info')
    execute(template)
