# -*- 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_switches, 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
        self.workDir = "/tmp"
        self.resultDir = None

def createResultsDir(resultDir, faces, hr):
    if faces == 0:
        faces = "all"

    if hr:
        routingType = "/hr/"
    else:
        routingType = "/ls/"

    resultDir = "%s/%s/faces-%s" % (str(resultDir), routingType, str(faces))
    resultDir = os.path.abspath(resultDir)

    if not os.path.isdir(resultDir):
        os.makedirs(resultDir)
    else:
        print("Results directory (%s) already exists!" % resultDir)
        sys.exit(1);

    print "Results will be stored at: %s" % resultDir
    return resultDir

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("--work-dir", action="store", dest="workDir", default="/tmp",
    help="Specify the working directory; default is /tmp")

    parser.add_option("--result-dir", action="store", dest="resultDir", default=None,
    help="Specify the full path destination folder where experiment results will be moved")

    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
    options.workDir = args.workDir
    options.resultDir = args.resultDir

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

    if options.experimentName is not None and options.resultDir is None:
        print "No results folder specified; experiment results will remain in the working directory"

    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, workDir, **opts):
        Topo.__init__(self, **opts)

        global hosts_conf
        global links_conf
        hosts_conf = parse_hosts(conf_arq)
        switches_conf = parse_switches(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, workdir=workDir)

        for switch in switches_conf:
            self.addSwitch(switch.name)

        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)

    if options.resultDir is not None:
        options.resultDir = createResultsDir(options.resultDir, options.nFaces, options.hr)

    topo = NdnTopo(template_file, options.workDir)

    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 node1 in net.switches or node2 in net.switches:
                continue

            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 options.resultDir is not None:
        print("Moving results to %s" % options.resultDir)
        os.system("sudo mv /%s/* %s" % (options.workDir, options.resultDir))

if __name__ == '__main__':

    hosts_conf = []
    links_conf = []

    options = parse_args()

    setLogLevel('info')
    execute(options)
