# Path: sts/util/console.py
# class msg():
#   global_io_master = None
# 
#   BEGIN = '\033[1;'
#   END = '\033[1;m'
# 
#   GRAY, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, CRIMSON = map(lambda num: str(num) + "m", range(30, 39))
#   B_BLACK, B_RED, B_GREEN, B_YELLOW, B_BLUE, B_MAGENTA, B_CYAN, B_GRAY, B_CRIMSON =  map(lambda num: str(num) + "m", range(40, 49))
# 
#   @staticmethod
#   def interactive(message):
#     # todo: would be nice to simply give logger a color arg, but that doesn't exist...
#     print msg.BEGIN + msg.WHITE + message + msg.END
# 
#   @staticmethod
#   def event(message):
#     print msg.BEGIN + msg.CYAN + message + msg.END
# 
#   @staticmethod
#   def openflow_event(message):
#     print msg.BEGIN + msg.BLUE + message + msg.END
# 
#   @staticmethod
#   def special_event(message):
#     print msg.BEGIN + msg.MAGENTA + message + msg.END
# 
#   @staticmethod
#   def replay_event_success(message):
#     print msg.BEGIN + msg.CYAN + msg.BEGIN + msg.B_BLUE + message + msg.END
# 
#   @staticmethod
#   def replay_event_timeout(message):
#     print msg.BEGIN + msg.MAGENTA + msg.BEGIN + msg.B_RED + message + msg.END
# 
#   @staticmethod
#   def mcs_event(message):
#     print msg.BEGIN + msg.B_MAGENTA + message + msg.END
# 
#   @staticmethod
#   def raw_input(message):
#     prompt = msg.BEGIN + msg.WHITE + message + msg.END
#     if msg.global_io_master:
#       s = msg.global_io_master.raw_input(prompt)
#     else:
#       s = raw_input(prompt)
# 
#     if s == "debug":
#       import pdb
#       pdb.set_trace()
#     return s
# 
#   @staticmethod
#   def success(message):
#     print msg.BEGIN + msg.B_GREEN + msg.BEGIN + msg.WHITE + message + msg.END
# 
#   @staticmethod
#   def fail(message):
#     print msg.BEGIN + msg.B_RED + msg.BEGIN + msg.WHITE + message + msg.END
# 
#   @staticmethod
#   def set_io_master(io_master):
#     msg.global_io_master = io_master
# 
#   @staticmethod
#   def unset_io_master():
#     msg.global_io_master = None


from pox.openflow.libopenflow_01 import *
from entities import *
from sts.util.console import msg
from collections import defaultdict
    from config_parser.openflow_parser import get_uniq_port_id
    from config_parser.openflow_parser import get_uniq_port_id
  from config_parser.openflow_parser import get_uniq_port_id
import logging
import collections
import time
    import topology_loader.topology_loader as hsa_topo
    import headerspace.applications as hsa
    import headerspace.applications as hsa
    import topology_loader.topology_loader as hsa_topo
    import headerspace.applications as hsa
    import topology_loader.topology_loader as hsa_topo
    import headerspace.applications as hsa
    import headerspace.applications as hsa
    import topology_loader.topology_loader as hsa_topo
    import headerspace.applications as hsa
    import topology_loader.topology_loader as hsa_topo
    unconnected_pairs = InvariantChecker._get_unconnected_pairs(simulation, connected_pairs)
    violations = [ str(pair) for pair in unconnected_pairs ]
    violations = list(set(violations))
    return violations

  @staticmethod
  def _python_get_connected_pairs(simulation):
    NTF = hsa_topo.generate_NTF(simulation.topology.live_switches)
    TTF = hsa_topo.generate_TTF(simulation.topology.live_links)
    paths = hsa.find_reachability(NTF, TTF, simulation.topology.access_links)
    # Paths is: in_port -> [p_node1, p_node2]
    # Where p_node is a hash:
    #  "hdr" -> foo
    #  "port" -> foo
    #  "visits" -> foo
    connected_pairs = set()
    for in_port, p_nodes in paths.iteritems():
      for p_node in p_nodes:
        connected_pairs.add((in_port, p_node["port"]))
    return connected_pairs

  @staticmethod
  def python_check_connectivity(simulation):
    ''' Return any pairs of hosts where there does not exist a path in the
    network between them '''
    # Warning! depends on python Hassell -- may be really slow!
    connected_pairs = InvariantChecker._python_get_connected_pairs(simulation)
    all_pairs = InvariantChecker._get_all_pairs(simulation)
    remaining_pairs = all_pairs - connected_pairs
    remaining_pairs = InvariantChecker._remove_partitioned_pairs(simulation, remaining_pairs)

# Path: sts/util/console.py
# class msg():
#   global_io_master = None
# 
#   BEGIN = '\033[1;'
#   END = '\033[1;m'
# 
#   GRAY, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, CRIMSON = map(lambda num: str(num) + "m", range(30, 39))
#   B_BLACK, B_RED, B_GREEN, B_YELLOW, B_BLUE, B_MAGENTA, B_CYAN, B_GRAY, B_CRIMSON =  map(lambda num: str(num) + "m", range(40, 49))
# 
#   @staticmethod
#   def interactive(message):
#     # todo: would be nice to simply give logger a color arg, but that doesn't exist...
#     print msg.BEGIN + msg.WHITE + message + msg.END
# 
#   @staticmethod
#   def event(message):
#     print msg.BEGIN + msg.CYAN + message + msg.END
# 
#   @staticmethod
#   def openflow_event(message):
#     print msg.BEGIN + msg.BLUE + message + msg.END
# 
#   @staticmethod
#   def special_event(message):
#     print msg.BEGIN + msg.MAGENTA + message + msg.END
# 
#   @staticmethod
#   def replay_event_success(message):
#     print msg.BEGIN + msg.CYAN + msg.BEGIN + msg.B_BLUE + message + msg.END
# 
#   @staticmethod
#   def replay_event_timeout(message):
#     print msg.BEGIN + msg.MAGENTA + msg.BEGIN + msg.B_RED + message + msg.END
# 
#   @staticmethod
#   def mcs_event(message):
#     print msg.BEGIN + msg.B_MAGENTA + message + msg.END
# 
#   @staticmethod
#   def raw_input(message):
#     prompt = msg.BEGIN + msg.WHITE + message + msg.END
#     if msg.global_io_master:
#       s = msg.global_io_master.raw_input(prompt)
#     else:
#       s = raw_input(prompt)
# 
#     if s == "debug":
#       import pdb
#       pdb.set_trace()
#     return s
# 
#   @staticmethod
#   def success(message):
#     print msg.BEGIN + msg.B_GREEN + msg.BEGIN + msg.WHITE + message + msg.END
# 
#   @staticmethod
#   def fail(message):
#     print msg.BEGIN + msg.B_RED + msg.BEGIN + msg.WHITE + message + msg.END
# 
#   @staticmethod
#   def set_io_master(io_master):
#     msg.global_io_master = io_master
# 
#   @staticmethod
#   def unset_io_master():
#     msg.global_io_master = None


# Path: sts/invariant_checker.py
from pox.openflow.libopenflow_01 import *
from entities import *
from sts.util.console import msg
from collections import defaultdict
    from config_parser.openflow_parser import get_uniq_port_id
    from config_parser.openflow_parser import get_uniq_port_id
  from config_parser.openflow_parser import get_uniq_port_id
import logging
import collections
import time
    import topology_loader.topology_loader as hsa_topo
    import headerspace.applications as hsa
    import headerspace.applications as hsa
    import topology_loader.topology_loader as hsa_topo
    import headerspace.applications as hsa
    import topology_loader.topology_loader as hsa_topo
    import headerspace.applications as hsa
    import headerspace.applications as hsa
    import topology_loader.topology_loader as hsa_topo
    import headerspace.applications as hsa
    import topology_loader.topology_loader as hsa_topo

    unconnected_pairs = InvariantChecker._get_unconnected_pairs(simulation, connected_pairs)
    violations = [ str(pair) for pair in unconnected_pairs ]
    violations = list(set(violations))
    return violations

  @staticmethod
  def _python_get_connected_pairs(simulation):
    NTF = hsa_topo.generate_NTF(simulation.topology.live_switches)
    TTF = hsa_topo.generate_TTF(simulation.topology.live_links)
    paths = hsa.find_reachability(NTF, TTF, simulation.topology.access_links)
    # Paths is: in_port -> [p_node1, p_node2]
    # Where p_node is a hash:
    #  "hdr" -> foo
    #  "port" -> foo
    #  "visits" -> foo
    connected_pairs = set()
    for in_port, p_nodes in paths.iteritems():
      for p_node in p_nodes:
        connected_pairs.add((in_port, p_node["port"]))
    return connected_pairs

  @staticmethod
  def python_check_connectivity(simulation):
    ''' Return any pairs of hosts where there does not exist a path in the
    network between them '''
    # Warning! depends on python Hassell -- may be really slow!
    connected_pairs = InvariantChecker._python_get_connected_pairs(simulation)
    all_pairs = InvariantChecker._get_all_pairs(simulation)
    remaining_pairs = all_pairs - connected_pairs
    remaining_pairs = InvariantChecker._remove_partitioned_pairs(simulation, remaining_pairs)

    return [ str(p) for p in list(remaining_pairs) ]