# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, 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, error, warn
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.experiments.experiment import Experiment
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.nfd import Nfd
from ndn.util import ssh, scp, MiniNDNCLI, ProgramOptions

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

try:
    import argcomplete
except ImportError:
    pass

VERSION_NUMBER = "0.4.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("  {}".format(experiment))

        sys.exit(0)

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:
        warn("Results directory ({}) already exists!".format(resultDir))
        sys.exit(1)

    info("Results will be stored at: {}".format(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")

    ExperimentManager.addExperimentArgs(parser)

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

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

    if options.experimentName is not None and options.experimentName not in ExperimentManager.getExperimentNames():
        error("No experiment named {}".format(options.experimentName))
        sys.exit(1)

    if options.experimentName is not None and options.resultDir is None:
        warn("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):
                error("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:
                    error("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)

        self.hosts_conf = parse_hosts(conf_arq)
        self.switches_conf = parse_switches(conf_arq)
        self.links_conf = parse_links(conf_arq)

        self.isTCLink = False
        self.isLimited = False

        for host in self.hosts_conf:
            if host.cpu != None and self.isLimited != True:
                self.isLimited = True
            self.addHost(host.name, app=host.app, params=host.params, cpu=host.cpu,
                         cores=host.cores,cache=host.cache, workdir=workDir)

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

        for link in self.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:
        error('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:
            error("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@{}".format(server)
                src = nfdConfFile
                dst = "{}:/tmp/nfd.conf".format(login)
                scp(src, dst)
                ssh(login, "sudo cp /tmp/nfd.conf {}".format(src))

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

    topo = NdnTopo(options.templateFile, options.workDir)

    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)

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

    for host in net.hosts:
        if 'app' in host.params:
            if host.params['app'] != '':
                app = host.params['app']
                info("Starting {} on node {}".format(app, host.name))
                info(host.cmd(app))

    # Determine if each host is running NFD
    for host in net.hosts:
        nfdStatus = host.cmd("ps -g -U root | grep 'nfd --config {}/[n]fd.conf'".format(host.homeFolder))
        if not host.nfd.isRunning or not nfdStatus:
            error("NFD on host {} is not running. Printing log file and exiting...".format(host.name))
            info(host.cmd("tail {}/nfd.log".format(host.homeFolder)))
            net.stop()
            sys.exit(1)

    # Load experiment
    experimentName = options.experimentName

    experimentArgs = {
        "net": net,
        "options": options
    }

    if experimentName is not None:
        info("Loading experiment: {}".format(experimentName))

        experiment = ExperimentManager.create(experimentName, experimentArgs)

        if experiment is not None:
            experiment.start()
        else:
            error("Experiment '{}' does not exist".format(experimentName))
            return
    else:
        experiment = Experiment(experimentArgs)
        if options.isNlsrEnabled:
            experiment.startNlsr(checkConvergence = False)

    if options.isCliEnabled is True:
        MiniNDNCLI(net)

    net.stop()

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

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

def verify_dependencies():
    "Prevent MiniNDN from running without necessary dependencies"
    dependencies = ["nfd", "nlsr", "infoedit", "ndnping", "ndnpingserver"]
    devnull = open("/dev/null", "w")
    # Checks that each program is in the system path
    for program in dependencies:
        if call(["which", program], stdout=devnull):
            error("{} is missing from the system path! Exiting...".format(program))
            sys.exit(1)
    devnull.close()

if __name__ == '__main__':

    signal.signal(signal.SIGQUIT, signal_handler)

    options = parse_args()

    setLogLevel('info')
    verify_dependencies()

    try:
        execute(options)
    except Exception as e:
        error("{}".format(e))
        call(["nfd-stop"])
        call(["sudo", "mn", "--clean"])
        sys.exit(1)
