# Path: minindn/helpers/nfdc.py
# class Nfdc(object):
#     STRATEGY_ASF = 'asf'
#     STRATEGY_BEST_ROUTE = 'best-route'
#     STRATEGY_MULTICAST = 'multicast'
#     STRATEGY_NCC = 'ncc'
#     PROTOCOL_UDP = 'udp'
#     PROTOCOL_TCP = 'tcp'
#     PROTOCOL_ETHER = 'ether'
# 
#     @staticmethod
#     def registerRoute(node, namePrefix, remoteNodeAddress, protocol=PROTOCOL_UDP, origin=255,
#                       cost=0, inheritFlag=True, captureFlag=False, expirationInMillis=None):
#         cmd = ('nfdc route add {} {}://{} origin {} cost {} {}{}{}').format(
#             namePrefix,
#             protocol,
#             remoteNodeAddress,
#             origin,
#             cost,
#             'no-inherit ' if not inheritFlag else '',
#             'capture ' if captureFlag else '',
#             'expires {}'.format(expirationInMillis) if expirationInMillis else ''
#         )
# 
#         debug(node.cmd(cmd))
#         Minindn.sleep(SLEEP_TIME)
# 
#     @staticmethod
#     def unregisterRoute(node, namePrefix, remoteNodeAddress, origin=255):
#         cmd = 'nfdc route remove {} {} {}'.format(namePrefix, remoteNodeAddress, origin)
#         debug(node.cmd(cmd))
#         Minindn.sleep(SLEEP_TIME)
# 
#     @staticmethod
#     def createFace(node, remoteNodeAddress, protocol='udp', isPermanent=False):
#         cmd = ('nfdc face create {}://{} {}'.format(
#             protocol,
#             remoteNodeAddress,
#             'permanent' if isPermanent else 'persistent'
#         ))
#         debug(node.cmd(cmd))
#         Minindn.sleep(SLEEP_TIME)
# 
#     @staticmethod
#     def destroyFace(node, remoteNodeAddress, protocol='udp'):
#         debug(node.cmd('nfdc face destroy {}://{}'.format(protocol, remoteNodeAddress)))
#         Minindn.sleep(SLEEP_TIME)
# 
#     @staticmethod
#     def setStrategy(node, namePrefix, strategy):
#         cmd = 'nfdc strategy set {} ndn:/localhost/nfd/strategy/{}'.format(namePrefix, strategy)
#         debug(node.cmd(cmd))
#         Minindn.sleep(SLEEP_TIME)
# 
#     @staticmethod
#     def unsetStrategy(node, namePrefix):
#         debug(node.cmd("nfdc strategy unset {}".format(namePrefix)))
#         Minindn.sleep(SLEEP_TIME)


import sys
import heapq
import json
import operator
from math import sin, cos, sinh, cosh, acos, acosh
from collections import defaultdict
from tqdm import tqdm
from mininet.log import info, debug, error, warn
from minindn.helpers.nfdc import Nfdc as nfdc
        """
        distanceMatrixViaNeighbor = self.getNestedDictionary()
        nodeNames = self.getNodeNames()
        for node in nodeNames:
            neighbors = [k for k in self.adjacenctMatrix[node]]
            for viaNeighbor in neighbors:
                directCost = self.adjacenctMatrix[node][viaNeighbor]
                distanceMatrixViaNeighbor[node][viaNeighbor][viaNeighbor] = directCost
                others = [x for x in nodeNames if x not in [viaNeighbor, node]]
                for destinationNode in others:
                    nodeNeighborCost = self.adjacenctMatrix[node][viaNeighbor]
                    # path variable is not used for now
                    cost, path = dijkstra(self.adjacenctMatrix, viaNeighbor, destinationNode, node)
                    if cost != 0 and path != None:
                        totalCost = cost + nodeNeighborCost
                        distanceMatrixViaNeighbor[node][destinationNode][viaNeighbor] = totalCost

        debug("Shortest Distance Matrix: {}".format(json.dumps(distanceMatrixViaNeighbor)))
        return distanceMatrixViaNeighbor

class NdnRoutingHelper(object):
    """
    This module is a helper class which helps to create face and register routes
    to NFD from a given node to all of its neighbors.

    :param NetObject netObject: Mininet net object
    :param FaceType faceType: UDP, Ethernet etc.
    :param Routing routingType: (optional) Routing algorithm, link-state or hr etc

    """

# Path: minindn/helpers/nfdc.py
# class Nfdc(object):
#     STRATEGY_ASF = 'asf'
#     STRATEGY_BEST_ROUTE = 'best-route'
#     STRATEGY_MULTICAST = 'multicast'
#     STRATEGY_NCC = 'ncc'
#     PROTOCOL_UDP = 'udp'
#     PROTOCOL_TCP = 'tcp'
#     PROTOCOL_ETHER = 'ether'
# 
#     @staticmethod
#     def registerRoute(node, namePrefix, remoteNodeAddress, protocol=PROTOCOL_UDP, origin=255,
#                       cost=0, inheritFlag=True, captureFlag=False, expirationInMillis=None):
#         cmd = ('nfdc route add {} {}://{} origin {} cost {} {}{}{}').format(
#             namePrefix,
#             protocol,
#             remoteNodeAddress,
#             origin,
#             cost,
#             'no-inherit ' if not inheritFlag else '',
#             'capture ' if captureFlag else '',
#             'expires {}'.format(expirationInMillis) if expirationInMillis else ''
#         )
# 
#         debug(node.cmd(cmd))
#         Minindn.sleep(SLEEP_TIME)
# 
#     @staticmethod
#     def unregisterRoute(node, namePrefix, remoteNodeAddress, origin=255):
#         cmd = 'nfdc route remove {} {} {}'.format(namePrefix, remoteNodeAddress, origin)
#         debug(node.cmd(cmd))
#         Minindn.sleep(SLEEP_TIME)
# 
#     @staticmethod
#     def createFace(node, remoteNodeAddress, protocol='udp', isPermanent=False):
#         cmd = ('nfdc face create {}://{} {}'.format(
#             protocol,
#             remoteNodeAddress,
#             'permanent' if isPermanent else 'persistent'
#         ))
#         debug(node.cmd(cmd))
#         Minindn.sleep(SLEEP_TIME)
# 
#     @staticmethod
#     def destroyFace(node, remoteNodeAddress, protocol='udp'):
#         debug(node.cmd('nfdc face destroy {}://{}'.format(protocol, remoteNodeAddress)))
#         Minindn.sleep(SLEEP_TIME)
# 
#     @staticmethod
#     def setStrategy(node, namePrefix, strategy):
#         cmd = 'nfdc strategy set {} ndn:/localhost/nfd/strategy/{}'.format(namePrefix, strategy)
#         debug(node.cmd(cmd))
#         Minindn.sleep(SLEEP_TIME)
# 
#     @staticmethod
#     def unsetStrategy(node, namePrefix):
#         debug(node.cmd("nfdc strategy unset {}".format(namePrefix)))
#         Minindn.sleep(SLEEP_TIME)


# Path: minindn/helpers/ndn_routing_helper.py
import sys
import heapq
import json
import operator
from math import sin, cos, sinh, cosh, acos, acosh
from collections import defaultdict
from tqdm import tqdm
from mininet.log import info, debug, error, warn
from minindn.helpers.nfdc import Nfdc as nfdc

        """
        distanceMatrixViaNeighbor = self.getNestedDictionary()
        nodeNames = self.getNodeNames()
        for node in nodeNames:
            neighbors = [k for k in self.adjacenctMatrix[node]]
            for viaNeighbor in neighbors:
                directCost = self.adjacenctMatrix[node][viaNeighbor]
                distanceMatrixViaNeighbor[node][viaNeighbor][viaNeighbor] = directCost
                others = [x for x in nodeNames if x not in [viaNeighbor, node]]
                for destinationNode in others:
                    nodeNeighborCost = self.adjacenctMatrix[node][viaNeighbor]
                    # path variable is not used for now
                    cost, path = dijkstra(self.adjacenctMatrix, viaNeighbor, destinationNode, node)
                    if cost != 0 and path != None:
                        totalCost = cost + nodeNeighborCost
                        distanceMatrixViaNeighbor[node][destinationNode][viaNeighbor] = totalCost

        debug("Shortest Distance Matrix: {}".format(json.dumps(distanceMatrixViaNeighbor)))
        return distanceMatrixViaNeighbor

class NdnRoutingHelper(object):
    """
    This module is a helper class which helps to create face and register routes
    to NFD from a given node to all of its neighbors.

    :param NetObject netObject: Mininet net object
    :param FaceType faceType: UDP, Ethernet etc.
    :param Routing routingType: (optional) Routing algorithm, link-state or hr etc

    """

    def __init__(self, netObject, faceType=nfdc.PROTOCOL_UDP, routingType="link-state"):