# -*- 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(option, opt, value, parser):
    experimentNames = ExperimentManager.getExperimentNames()

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

    sys.exit()

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

class ProgramOptions:
    def __init__(self):
        self.ctime = 60
        self.experimentName = None
        self.nFaces = 3
        self.templateFile = "minindn.conf"
        self.hr = False
        self.isCliEnabled = True
        self.nPings = 300
        self.testbed = False

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

    parser = optparse.OptionParser(usage)

    parser.add_option("--ctime", action="store", dest="ctime", type="int", default=60,
    help="Specify convergence time for the topology (Default: 60 seconds)")

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

    parser.add_option("--faces", action="store", dest="faces", type="int", default=3,
    help="Specify number of faces 0-60")

    parser.add_option("--hr", action="store_true", dest="hr", default=False,
    help="--hr is used to turn on hyperbolic routing")

    parser.add_option("--list-experiments", action="callback", callback=printExperimentNames,
    help="Lists the names of all available experiments")

    parser.add_option("--no-cli", action="store_false", dest="isCliEnabled", default=True,
    help="Run experiments and exit without showing the command line interface")

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

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

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

    (args, arg) = parser.parse_args()

    options = ProgramOptions()
    options.ctime = args.ctime
    options.experimentName = args.experiment
    options.nFaces = args.faces
    options.hr = args.hr
    options.isCliEnabled = args.isCliEnabled
    options.nPings = args.nPings
    options.testbed = args.testbed

    if options.experimentName is not None and options.experimentName not in ExperimentManager.getExperimentNames():
        print("No experiment named %s" % options.experimentName)
        sys.exit()

    if len(arg) == 0 or len(arg) > 2:
        options.templateFile = ''
    else:
        options.templateFile = arg[0]

    return options

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(options):
    "Create a network based on template_file"

    template_file = options.templateFile
    install_dir='/usr/local/etc/mini-ndn/'

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

    if options.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 options.nFaces is not None:
            host.nlsrParameters["max-faces-per-prefix"] = options.nFaces

        if options.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
    experimentName = options.experimentName

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

        experimentArgs = {
            "net": net,
            "nodes": nodes,
            "ctime": options.ctime,
            "nPings": options.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 options.isCliEnabled is True:
        CLI(net)

    net.stop()

if __name__ == '__main__':

    hosts_conf = []
    links_conf = []

    options = parse_args()

    setLogLevel('info')
    execute(options)
