# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015 The University of Memphis,
#                    Arizona Board of Regents,
#                    Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
#
# This file incorporates work covered by the following copyright and
# permission notice:
#
#   Mininet 2.2.1 License
#
#   Copyright (c) 2013-2015 Open Networking Laboratory
#   Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
#   The Leland Stanford Junior University
#
#   Original authors: Bob Lantz and Brandon Heller
#
#   We are making Mininet available for public use and benefit with the
#   expectation that others will use, modify and enhance the Software and
#   contribute those enhancements back to the community. However, since we
#   would like to make the Software available for broadest use, with as few
#   restrictions as possible permission is hereby granted, free of charge, to
#   any person obtaining a copy of this Software to deal in the Software
#   under the copyrights without restriction, including without limitation
#   the rights to use, copy, modify, merge, publish, distribute, sublicense,
#   and/or sell copies of the Software, and to permit persons to whom the
#   Software is furnished to do so, subject to the following conditions:
#
#   The above copyright notice and this permission notice shall be included
#   in all copies or substantial portions of the Software.
#
#   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
#   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
#   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
#   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
#   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
#   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
#   The name and trademarks of copyright holder(s) may NOT be used in
#   advertising or publicity pertaining to the Software or any derivatives
#   without specific, written prior permission.

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

VERSION_NUMBER = "0.1.0"

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

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

def printVersion(option, opt, value, parser):
    print "Mini-NDN v%s" % VERSION_NUMBER
    sys.exit()

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

    parser.add_option('--version', '-V', action='callback', callback=printVersion,
    help='Displays version information')

    (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 experimentName is not None and experimentName not in ExperimentManager.getExperimentNames():
        print("No experiment named %s" % experimentName)
        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, params=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()

    # Update nfd.conf file used by Mini-NDN to match the currently installed version of NFD
    nfdConfFile = "%s/nfd.conf" % install_dir
    os.system("sudo cp /usr/local/etc/ndn/nfd.conf.sample %s" % nfdConfFile)
    os.system("sudo sed -i \'s|default_level [A-Z]*$|default_level $LOG_LEVEL|g\' %s" % nfdConfFile)

    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'] != '':
                app = host.params['app']
                print "Starting " + app + " on node " + host.name
                print(host.cmd(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)
