# -*- 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

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

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

        sys.exit(0)

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.nlsrSecurity = False
        self.nPings = 300
        self.testbed = False
        self.workDir = "/tmp"
        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"

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():
    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, ndn_utils/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",
                        help="Runs the specified experiment")

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

    # store_true stores default value of False
    parser.add_argument("--hr", action="store_true",
                        help="--hr is used to turn on hyperbolic 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")

    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",
                        help="Specify the working directory; default is /tmp")

    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'])

    args = parser.parse_args()

    options = ProgramOptions()
    options.templateFile = args.tempfile
    options.ctime = args.ctime
    options.experimentName = args.experiment
    options.nFaces = args.faces
    options.hr = args.hr
    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

    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)

        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)

    # Use nfd.conf as default configuration for NFD, else use the sample

    nfdConfFile = "%s/nfd.conf" % INSTALL_DIR
    if os.path.isfile("/usr/local/etc/ndn/nfd.conf") == True:
        shutil.copy2("/usr/local/etc/ndn/nfd.conf", nfdConfFile)
    elif os.path.isfile("/usr/local/etc/ndn/nfd.conf.sample") == True:
        shutil.copy2("/usr/local/etc/ndn/nfd.conf.sample", nfdConfFile)
    else:
        sys.exit("nfd.conf or nfd.conf.sample cannot be found in the expected directory. Exit.")

    call(["sudo", "sed", "-i", 's|default_level [A-Z]*$|default_level $LOG_LEVEL|g', nfdConfFile])

    # 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.hr)

    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)

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

    # NLSR initialization
    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.hr is True:
            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
        }

        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.SIGINT, signal_handler)

    options = parse_args()

    setLogLevel('info')
    execute(options)
