# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2017, 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.3.0d1 License
#
#   Copyright (c) 2013-2016 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.link import TCLink
from mininet.util import ipStr, ipParse

from mininet.examples.cluster import MininetCluster, RoundRobinPlacer, ClusterCleanup
from mininet.examples.clustercli import ClusterCLI

from ndn import ExperimentManager
from ndn.ndn_host import NdnHost, CpuLimitedNdnHost, RemoteNdnHost
from ndn.conf_parser import parse_hosts, parse_switches, parse_links
from ndn.remote_ndn_link import RemoteNdnLink, RemoteGRENdnLink
from ndn.placer import GuidedPlacer, PopulatePlacement
from ndn.util import ssh, scp, MiniNDNCLI

import os.path, time
import shutil
import argparse
import datetime
from os.path import expanduser
import sys
import signal
from subprocess import call
import glob
from functools import partial
import re

from ndn.nlsr import Nlsr, NlsrConfigGenerator
from ndn.nfd import Nfd

try:
    import argcomplete
except ImportError:
    pass

VERSION_NUMBER = "0.3.0"
INSTALL_DIR='/usr/local/etc/mini-ndn/'

class PrintExperimentNames(argparse.Action):
    def __init__(self, option_strings, dest, nargs=0, help=None):
        super(PrintExperimentNames, self).__init__(option_strings=option_strings, dest=dest, nargs=nargs, help=help)

    def __call__(self, parser, namespace, values, option_string=None):
        experimentNames = ExperimentManager.getExperimentNames()
        experimentArgs = ExperimentManager.getExperimentArgs()

        print("Mini-NDN experiments:")
        for experiment in experimentNames:
            print("  {}".format(experiment))
            if experiment in experimentArgs:
                print("      ({})".format(experimentArgs[experiment]))

        sys.exit(0)

class ProgramOptions:
    def __init__(self):
        self.ctime = 60
        self.experimentName = None
        self.nFaces = 3
        self.templateFile = "minindn.conf"
        self.routingType = "link-state"
        self.isNlsrEnabled = True
        self.isCliEnabled = True
        self.nlsrSecurity = False
        self.nPings = 300
        self.testbed = False
        self.workDir = "/tmp/minindn"
        self.resultDir = None
        self.pctTraffic = 1.0
        self.cluster = None
        self.servers = None
        self.guided = None
        self.placer = None
        self.tunnelType = None
        self.faceType = "udp"
        self.arbArgs = {}
        self.csSize = 65536

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

    routingChoice = "/{}/".format(rType)

    resultDir = "{}/{}/faces-{}".format(resultDir, routingChoice, 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():
    parser = argparse.ArgumentParser(prog='minindn')

    # nargs='?' required here since optional argument
    parser.add_argument('tempfile', nargs='?', default=INSTALL_DIR + 'default-topology.conf',
                        help="If no template_file is given, topologies/default-topology.conf (given sample file) will be used.")

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

    parser.add_argument("--experiment", choices=[experiment for experiment in ExperimentManager.getExperimentNames()],
                        help="Runs the specified experiment")

    parser.add_argument("--faces", type=int, default=3,
                        help="Specify number of max faces per prefix for NLSR 0-60")

    parser.add_argument("--routing", dest="routingType", default='link-state', choices=['link-state', 'hr', 'dry'],
                        help="""choices for routing are 'link-state' for link state, 'hr' for hyperbolic, and 'dry'
                        to test hyperbolic routing and compare with link state. Default is link-state.""")

    parser.add_argument("--no-nlsr", action="store_false", dest="isNlsrEnabled",
                        help="Run mini-ndn without NLSR routing")

    parser.add_argument("--list-experiments", action=PrintExperimentNames,
                        help="Lists the names of all available experiments")

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

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

    # store_true stores default value of False
    parser.add_argument("--nlsr-security", action="store_true", dest="nlsrSecurity",
                        help="Enables NLSR security")

    parser.add_argument("-t", "--testbed", action="store_true", dest="testbed",
                         help="Instantiates a snapshot of the NDN Testbed irrespective of the tempfile provided")

    parser.add_argument("--work-dir", action="store", dest="workDir", default="/tmp/minindn",
                        help="Specify the working directory; default is /tmp/minindn")

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

    parser.add_argument("--pct-traffic", dest="pctTraffic", type=float, default=1.0,
                        help="Specify the percentage of nodes each node should ping")

    parser.add_argument('--version', '-V', action='version', version='%(prog)s ' + VERSION_NUMBER,
                        help='Displays version information')

    parser.add_argument("--cluster", metavar='localhost,server2,...',
                        help="Run cluster edition")

    parser.add_argument("--placement", default='guided',
                        choices=['roundRobin', 'guided'])

    parser.add_argument("--place-list", dest="placeList",
                        help="""Provide corresponding number of nodes (comma separated) to put on
                        each node respectively of --cluster when guided placement is used""")

    parser.add_argument("--tunnel-type", dest="tunnelType", default='ssh',
                        choices=['ssh', 'gre'])

    parser.add_argument("--face-type", dest='faceType', default='udp', choices=['udp', 'tcp'])

    parser.add_argument("--cs-size", dest='csSize', type=int, default=65536,
                        help="Set CS size in NFD's conf file")

    if "argcomplete" in sys.modules:
        argcomplete.autocomplete(parser)

    args, unknownArgs = parser.parse_known_args()

    unknownArgsList = []
    for arg in unknownArgs:
        if arg.startswith(("--")):
            parser.add_argument(arg)
            unknownArgsList.append(arg.split("--")[1])

    args = parser.parse_args()

    options = ProgramOptions()
    options.templateFile = args.tempfile
    options.ctime = args.ctime
    options.experimentName = args.experiment
    options.nFaces = args.faces
    options.routingType = args.routingType
    options.isNlsrEnabled = args.isNlsrEnabled
    options.isCliEnabled = args.isCliEnabled
    options.nlsrSecurity = args.nlsrSecurity
    options.nPings = args.nPings

    options.testbed = args.testbed
    options.workDir = args.workDir
    options.resultDir = args.resultDir
    options.pctTraffic = args.pctTraffic
    options.cluster = args.cluster
    options.placement = args.placement
    options.tunnelType = args.tunnelType
    options.placeList = args.placeList
    options.faceType = args.faceType
    options.csSize = args.csSize

    for k in args.__dict__:
        if k in unknownArgsList:
            options.arbArgs[k] = args.__dict__[k]

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

    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 options.cluster is not None:
        servers = options.cluster.split(',')
        for server in servers:
            ClusterCleanup.add(server)
        options.servers = servers

        if options.placement == "roundRobin":
            options.placement = RoundRobinPlacer
        elif options.placement == "guided":
            if options.placeList is None or not re.match("^[0-9,]+$", options.placeList):
                print("Please specify correctly how many nodes you want to place on each node!")
                sys.exit(1)
            else:
                try:
                    options.placeList = map(int, options.placeList.split(","))
                except ValueError:
                    print("Please specify the nodes correctly, no comma at the beginning/end!")
                    sys.exit(1)

                PopulatePlacement(options.placeList)
                options.placement = GuidedPlacer

        if options.tunnelType == "ssh":
            options.tunnelType = RemoteNdnLink
        else:
            options.tunnelType = RemoteGRENdnLink

    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)
            if (options.routingType != 'link-state' and (host.params.get('radius') is None
                or host.params.get('angle') is None)):
                info('Hyperbolic coordinates in topology file are either missing or misconfigured.\n' \
                     'Check that each node has one radius value and one or two angle value(s).\n')
                sys.exit(1)

        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"

    if options.testbed:
        options.templateFile = INSTALL_DIR + 'minindn.testbed.conf'

    if os.path.exists(options.templateFile) == False:
        info('Template file cannot be found. Exiting...\n')
        sys.exit(1)

    if options.cluster is not None and options.placement == GuidedPlacer:
        num_nodes = 0
        with open(options.templateFile, 'r') as topo:
            for line in topo:
                if ': _' in line:
                    num_nodes += 1

        if sum(options.placeList) != num_nodes:
            print("Placement list sum is not equal to number of nodes!")
            sys.exit(1)

    # Copy nfd.conf to remote hosts - this assumes that NDN versions across
    # the cluster are at least compatible if not the same
    if options.cluster is not None:
        for server in options.servers:
            if server != "localhost":
                login = "mininet@%s" % server
                src = nfdConfFile
                dst = "%s:/tmp/nfd.conf" % (login)
                scp(src, dst)
                ssh(login, "sudo cp /tmp/nfd.conf %s" % src)

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

    topo = NdnTopo(options.templateFile, 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:
        if options.cluster is not None:
            mn = partial(MininetCluster, servers=options.servers, placement=options.placement)
            net = mn(topo=topo, host=RemoteNdnHost, link=options.tunnelType)
        else:
            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)

    time.sleep(2)
    info('Starting NFD on nodes\n')
    for host in net.hosts:
        host.nfd = Nfd(host, options.csSize)
        host.nfd.start()

    if options.isNlsrEnabled is True:

        # NLSR Security
        if options.nlsrSecurity is True:
            Nlsr.createKeysAndCertificates(net, options.workDir)

        # NLSR initialization
        info('Starting NLSR on nodes\n')
        for host in net.hosts:
            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.routingType == 'dry':
                host.nlsrParameters["hyperbolic-state"] = "dry-run"

            elif options.routingType == 'hr':
                host.nlsrParameters["hyperbolic-state"] = "on"

            # Generate NLSR configuration file
            configGenerator = NlsrConfigGenerator(host, options.nlsrSecurity, options.faceType)
            configGenerator.createConfigFile()

            # Start NLSR
            host.nlsr = Nlsr(host, configGenerator.neighborIPs, options.faceType)
            host.nlsr.start()

    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,
            "ctime": options.ctime,
            "nPings": options.nPings,
            "strategy": Nfd.STRATEGY_BEST_ROUTE,
            "pctTraffic": options.pctTraffic,
            "nlsrSecurity": options.nlsrSecurity,
            "workDir": options.workDir,
            "arbArgs" : options.arbArgs
        }

        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:
        MiniNDNCLI(net)

    net.stop()

    if options.resultDir is not None:
        print("Moving results to %s" % options.resultDir)
        for file in glob.glob('%s/*' % options.workDir):
            shutil.move(file, options.resultDir)
        if options.cluster is not None:
            for server in options.servers:
                if server != "localhost":
                    login = "mininet@%s" % server
                    src = "%s:%s/*" % (login, options.workDir)
                    dst = options.resultDir
                    scp(src, dst)
            print("Please clean work directories of other machines before running the cluster again")

def signal_handler(signal, frame):
    print('Cleaning up...')
    call(["nfd-stop"])
    call(["sudo", "mn", "--clean"])
    sys.exit(1)

if __name__ == '__main__':

    hosts_conf = []
    links_conf = []

    signal.signal(signal.SIGQUIT, signal_handler)

    options = parse_args()

    setLogLevel('info')

    # No exceptions are raised in ndn presently, and Mininet relies
    # on generic Exception. If this situation changes this may well
    # need to be altered.
    try:
        execute(options)
    except Exception as e:
        print("Mininet Error: {}".format(e))
        call(["nfd-stop"])
        call(["sudo", "mn", "--clean"])
        sys.exit(1)