# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2021, 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/>.

import os
import argparse
import sys
import configparser
from subprocess import Popen, PIPE

from mininet.log import info, debug

from mn_wifi.topo import Topo as Topo_WiFi
from mn_wifi.net import Mininet_wifi
from mn_wifi.link import WirelessLink
from mn_wifi.link import wmediumd, adhoc

from minindn.minindn import Minindn
from minindn.helpers.nfdc import Nfdc

import ast

class MinindnWifi(Minindn):
    """ Class for handling default args, Mininet-wifi object and home directories """
    def __init__(self, parser=argparse.ArgumentParser(), topo=None, topoFile=None, noTopo=False,
                 link=WirelessLink, workDir=None, **mininetParams):
        """
        Create Mini-NDN-Wifi object
        parser: Parent parser of Mini-NDN-Wifi parser (use to specify experiment arguments)
        topo: Mininet topo object (optional)
        topoFile: topology file location (optional)
        noTopo: Allows specification of topology after network object is initialized (optional)
        link: Allows specification of default Mininet/Mininet-Wifi link type for
        connections between nodes (optional)mininetParams: Any params to pass to Mininet-WiFi
        """
        self.parser = self.parseArgs(parser)
        self.args = self.parser.parse_args()

        if not workDir:
            Minindn.workDir = os.path.abspath(self.args.workDir)
        else:
            Minindn.workDir = os.path.abspath(workDir)

        Minindn.resultDir = self.args.resultDir

        self.topoFile = None
        if not topoFile:
            # Args has default topology if none specified
            self.topoFile = self.args.topoFile
        else:
            self.topoFile = topoFile

        self.faces_to_create = {}
        if topo is None and not noTopo:
            try:
                info('Using topology file {}\n'.format(self.topoFile))
                self.topo, self.faces_to_create = self.processTopo(self.topoFile)
            except configparser.NoSectionError as e:
                info('Error reading config file: {}\n'.format(e))
                sys.exit(1)
        else:
            self.topo = topo

        if not noTopo:
            self.net = Mininet_wifi(topo=self.topo, ifb=self.args.ifb, link=link, **mininetParams)
        else:
            self.net = Mininet_wifi(ifb=self.args.ifb, link=link, **mininetParams)

        # process mobility if specified
        if not noTopo:
            self.processMobility(self.topoFile)

        # Prevents crashes running mixed topos
        nodes = self.net.stations + self.net.hosts + self.net.cars
        self.initParams(nodes)

        try:
            process = Popen(['ndnsec-get-default', '-k'], stdout=PIPE, stderr=PIPE)
            output, error = process.communicate()
            if process.returncode == 0:
                Minindn.ndnSecurityDisabled = '/dummy/KEY/-%9C%28r%B8%AA%3B%60' in output.decode("utf-8")
                info('Dummy key chain patch is installed in ndn-cxx. Security will be disabled.\n')
            else:
                debug(error + "\n")
        except:
            pass

        self.cleanups = []

    @staticmethod
    def parseArgs(parent):
        parser = argparse.ArgumentParser(prog='minindn-wifi', parents=[parent], add_help=False)

        # nargs='?' required here since optional argument
        parser.add_argument('topoFile', nargs='?', default='/usr/local/etc/mini-ndn/singleap-topology.conf',
                            help='If no template_file is given, topologies/wifi/singleap-topology.conf will be used.')

        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('--mobility',action='store_true',dest='mobility',default=False,
                            help='Enable custom mobility for topology (defined in topology file)')

        parser.add_argument('--ifb',action='store_true',dest='ifb',default=False,
                            help='Simulate delay on receiver-side by use of virtual IFB devices (see docs)')

        return parser

    @staticmethod
    def convert_params(params):
        converted_params = {}
        for key, value in params.items():
            try:
                converted_params[key] = ast.literal_eval(value)
            except (ValueError, SyntaxError):
                converted_params[key] = value
        return converted_params

    @staticmethod
    def processTopo(topoFile):
        config = configparser.ConfigParser(delimiters=' ')
        config.read(topoFile)
        topo = Topo_WiFi()

        items = config.items('stations')
        debug("Stations\n")
        for item in items:
            debug(str(item[0].split(':'))+"\n")
            name = item[0].split(':')[0]
            params = {}
            for param in item[1].split(' '):
                    if param == "_":
                        continue
                    key = param.split('=')[0]
                    value = param.split('=')[1]
                    if key in ['range']:
                        value = int(value)
                    params[key] = value

            topo.addStation(name, **params)

        try:
            debug("Switches\n")
            items = config.items('switches')
            for item in items:
                debug(str(item[0].split(':'))+"\n")
                name = item[0].split(':')[0]
                topo.addSwitch(name)
        except configparser.NoSectionError:
            debug("Switches are optional\n")
            pass

        try:
            debug("APs")
            items = config.items('accessPoints')
            for item in items:
                debug(str(item[0].split(':'))+"\n")
                name = item[0].split(':')[0]
                ap_params = {}
                for param in item[1].split(' '):
                    if param == "_":
                        continue
                    key = param.split('=')[0]
                    value = param.split('=')[1]
                    if key in ['range']:
                        value = int(value)
                    ap_params[key] = value
                topo.addAccessPoint(name, **ap_params)
        except configparser.NoSectionError:
            debug("APs are optional\n")
            pass

        items = config.items('links')
        debug("Links")
        for item in items:
            link = item[0].split(':')
            debug(str(link) + "\n")
            params = {}
            for param in item[1].split(' '):
                if param == "_":
                    continue
                key = param.split('=')[0]
                value = param.split('=')[1]
                if key in ['jitter', 'max_queue_size']:
                    value = int(value)
                if key in ['loss', 'bw']:
                    value = float(value)
                params[key] = value

            topo.addLink(link[0], link[1], **params)

        faces = {}
        try:
            items = config.items('faces')
            debug("Faces\n")
            for item in items:
                face_a, face_b = item[0].split(':')
                debug(str(item)+"\n")
                cost = -1
                for param in item[1].split(' '):
                    if param.split("=")[0] == 'cost':
                        cost = param.split("=")[1]
                face_info = (face_b, int(cost))
                if face_a not in faces:
                    faces[face_a] = [face_info]
                else:
                    faces[face_a].append(face_info)
        except configparser.NoSectionError:
            debug("Faces section is optional\n")
            pass

        return (topo, faces)

    def processMobility(self, topoFile):
        config = configparser.ConfigParser(delimiters=' ')
        config.read(topoFile)

        try:
            debug("Mobility\n")
            items = config.items('mobility')
            if len(items) == 0:
                return
            params = {}
            for param in items[0][1].split(' '):
                if param == "_":
                    continue
                key = param.split('=')[0]
                value = param.split('=')[1]
                params[key] = value
            params = self.convert_params(params)
            self.startMobilityModel(**params)

            items = config.items('stations')
            debug("Start Mobility\n")
            for item in items:
                debug(str(item[0].split(':'))+"\n")
                name = item[0].split(':')[0]
                params = {}
                for param in item[1].split(' '):
                    if param == "_":
                        continue
                    key = param.split('=')[0]
                    value = param.split('=')[1]
                    if key in ['range']:
                        value = int(value)
                    params[key] = value
                # by default, nodes are moving
                if "moving" not in params or params["moving"] == "True":
                    self.net.mobility(self.net[name],'start', time=0, **params)

        except configparser.NoSectionError:
            debug("Mobility section is optional\n")

    def startMobility(self, max_x=1000, max_y=1000, **kwargs):
        """ Method to run a basic mobility setup on your net"""
        self.net.plotGraph(max_x=max_x, max_y=max_y)
        self.net.startMobility(**kwargs)

    def startMobilityModel(self, max_x=1000, max_y=1000, **kwargs):
        """ Method to run a mobility model on your net until exited"""
        self.net.plotGraph(max_x=max_x, max_y=max_y)
        self.net.setMobilityModel(**kwargs)

    def getWifiInterfaceDelay(self, node, interface=None):
        """Method to return the configured tc delay of a wifi node's interface as a float"""
        if not interface:
            wifi_interface = "{}-wlan0".format(node.name)
        else:
            wifi_interface = interface
        tc_output = node.cmd("tc qdisc show dev {}".format(wifi_interface))
        for line in tc_output.splitlines():
            if "qdisc netem 10:" in line:
                split_line = line.split(" ")
                for index in range(0, len(split_line)):
                    if split_line[index] == "delay":
                        return float(split_line[index + 1][:-2])
        return 0.0

    def setupFaces(self, faces_to_create=None):
        """
        Method to create unicast faces between nodes connected by an AP based on name or faces
        between connected nodes; Returns dict- {node: (other node name, other node IP, other
        node's delay as int)}. This is intended to pass to the NLSR helper via the faceDict param
        """
        if not faces_to_create:
            faces_to_create = self.faces_to_create
        # (nodeName, IP, delay as int)
        # list of tuples
        created_faces = dict()
        batch_faces = dict()
        for nodeAname in faces_to_create.keys():
            if not nodeAname in batch_faces.keys():
                batch_faces[nodeAname] = []
            for nodeBname, faceCost in faces_to_create[nodeAname]:
                if not nodeBname in batch_faces.keys():
                    batch_faces[nodeBname] = []
                nodeA = self.net[nodeAname]
                nodeB = self.net[nodeBname]
                if nodeA.connectionsTo(nodeB):
                    best_interface = None
                    delay = None
                    for interface in nodeA.connectionsTo(nodeB):
                        interface_delay = self.getInterfaceDelay(nodeA, interface[0])
                        if not delay or int(interface_delay) < delay:
                            best_interface = interface
                    faceAIP = best_interface[0].IP()
                    faceBIP = best_interface[1].IP()
                    # Node delay should be symmetrical
                    nodeDelay = int(self.getInterfaceDelay(nodeA, best_interface[0]))
                else:
                    # Default IP will be the primary wireless interface, unclear if multiple wireless
                    # interfaces should be handled
                    faceAIP = nodeA.IP()
                    faceBIP = nodeB.IP()
                    nodeADelay = self.getWifiInterfaceDelay(nodeA)
                    nodeBDelay = self.getWifiInterfaceDelay(nodeB)
                    nodeDelay = nodeADelay + nodeBDelay

                if not faceCost == -1:
                    nodeALink = (nodeA.name, faceAIP, faceCost)
                    nodeBLink = (nodeB.name, faceBIP, faceCost)
                else:
                    nodeALink = (nodeA.name, faceAIP, nodeDelay)
                    nodeBLink = (nodeB.name, faceBIP, nodeDelay)

                batch_faces[nodeAname].append([faceBIP, "udp", True])
                batch_faces[nodeBname].append([faceAIP, "udp", True])

                if nodeA not in created_faces:
                    created_faces[nodeA] = [nodeBLink]
                else:
                    created_faces[nodeA].append(nodeBLink)
                if nodeB not in created_faces:
                    created_faces[nodeB] = [nodeALink]
                else:
                    created_faces[nodeB].append(nodeALink)
        for station_name in batch_faces.keys():
            self.nfdcBatchProcessing(self.net[station_name], batch_faces[station_name])
        return created_faces

class MinindnAdhoc(MinindnWifi):
    """
    Class for ad hoc network of Mininet-wifi
    Topology example: topologies/wifi/adhoc-topology.conf
    The link type is wmediumd by default
    """
    def __init__(self, parser=argparse.ArgumentParser(), topo=None, topoFile=None, noTopo=False,
                 link=wmediumd, workDir=None, **mininetParams):
        # call parent constructor
        super().__init__(parser, topo, topoFile, noTopo, link, workDir, **mininetParams)
        if not self.topoFile:
            info("Without topoFile, ad hoc links are not added to the network, and you need to"
                 " add them manually. The example topology file can be found in"
                 " topologies/wifi/adhoc-topology.conf\n")
        else:
            self.addAdhocLinks()

    @staticmethod
    def parseArgs(parent):
        parser = argparse.ArgumentParser(prog='minindn-adhoc', parents=[parent], add_help=False)

        # nargs='?' required here since optional argument
        parser.add_argument('topoFile', nargs='?', default='/usr/local/etc/mini-ndn/adhoc-topology.conf',
                            help='If no template_file is given, topologies/wifi/adhoc-topology.conf will be used.')

        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('--mobility',action='store_true',dest='mobility',default=False,
                            help='Enable custom mobility for topology (defined in topology file)')

        parser.add_argument('--ifb',action='store_true',dest='ifb',default=False,
                            help='Simulate delay on receiver-side by use of virtual IFB devices (see docs)')

        return parser

    @staticmethod
    def processTopo(topoFile):
        config = configparser.ConfigParser(delimiters=' ')
        config.read(topoFile)
        topo = Topo_WiFi()

        items = config.items('stations')
        debug("Stations\n")
        id = 0
        for item in items:
            debug(str(item[0].split(':'))+"\n")
            name = item[0].split(':')[0]
            params = {}
            for param in item[1].split(' '):
                    if param == "_":
                        continue
                    key = param.split('=')[0]
                    value = param.split('=')[1]
                    if key in ['range']:
                        value = int(value)
                    params[key] = value
            # ip6 address for each station using id
            if 'ip6' not in params:
                params['ip6'] = 'fe80::{}'.format(id)
            topo.addStation(name, **params)
            id += 1

        faces = {}
        try:
            items = config.items('faces')
            debug("Faces\n")
            for item in items:
                face_a, face_b = item[0].split(':')
                debug(str(item)+"\n")
                cost = -1
                for param in item[1].split(' '):
                    if param.split("=")[0] == 'cost':
                        cost = param.split("=")[1]
                face_info = (face_b, int(cost))
                if face_a not in faces:
                    faces[face_a] = [face_info]
                else:
                    faces[face_a].append(face_info)
        except configparser.NoSectionError:
            debug("Faces section is optional\n")
            pass

        return (topo, faces)

    """Add adhoc links to the network"""
    # In the topo.py, all the links require two stations, but in adhoc topology, we need to add links for all the nodes.
    def addAdhocLinks(self):
        config = configparser.ConfigParser(delimiters=' ')
        config.read(self.topoFile)

        # read adhoc network parameters
        # return if adhoc network is not defined
        if 'adhocNetwork' not in config.sections():
            info("Adhoc network is not defined in the topology file\n")
            return

        adhoc_params = config.items('adhocNetwork')
        params = {}
        for param in adhoc_params[0][1].split(' '):
            if param == "_":
                continue
            key = param.split('=')[0]
            value = param.split('=')[1]
            if key in ['range']:
                value = int(value)
            params[key] = value
        params = self.convert_params(params)

        # return if ssid, mode, channel not defined in params
        if 'ssid' not in params or 'mode' not in params or 'channel' not in params:
            info("ssid, mode, channel not defined in adhoc network parameters\n")
            return
        networkParams = params

        # add adhoc links
        debug("Links\n")
        items = config.items('stations')
        for item in items:
            debug(str(item[0].split(':'))+"\n")
            name = item[0].split(':')[0]
            params = {}
            for param in item[1].split(' '):
                    if param == "_":
                        continue
                    key = param.split('=')[0]
                    value = param.split('=')[1]
                    params[key] = value
            params = self.convert_params(params)
            # replace | with space in bitrates because space is not allowed in the configuration file
            if 'bitrates' in params:
                params['bitrates'] = params['bitrates'].replace("|", " ")
            self.net.addLink(name, cls=adhoc, intf='{}-wlan0'.format(name), **networkParams, **params)
