# Path: xctrl/flowmodmsg.py
# class FlowModMsgBuilder(object):
#     def __init__(self, participant, key):
#         self.participant = participant
#         self.key = key
#         self.flow_mods = []
# 
#     def add_flow_mod(self, mod_type, rule_type, priority, match, action, cookie = None):
#         if cookie is None:
#             cookie = (len(self.flow_mods)+1, 65535)
# 
#         fm = {
#                "cookie": cookie,
#                "mod_type": mod_type,
#                "rule_type": rule_type,
#                "priority": priority,
#                "match": match,
#                "action": action
#              }
# 
#         self.flow_mods.append(fm)
# 
#         return cookie
# 
#     def delete_flow_mod(self, mod_type, rule_type, cookie, cookie_mask):
#         fm = {
#             "cookie": (cookie, cookie_mask),
#             "mod_type": mod_type,
#             "rule_type": rule_type,
#         }
# 
#         self.flow_mods.append(fm)
# 
#     def get_msg(self):
#         msg = {
#                 "auth_info": {
#                                "participant" : self.participant,
#                                "key" : self.key
#                              },
#                 "flow_mods": self.flow_mods
#               }
# 
#         return msg


import argparse
import atexit
import json
import os
import time
import sys
import util.log
import pprint
from multiprocessing.connection import Listener, Client
from signal import signal, SIGTERM
from sys import exit
from threading import RLock, Thread
from xctrl.flowmodmsg import FlowModMsgBuilder
from lib import PConfig
from peer import BGPPeer
from ss_lib import vmac_part_port_match
from ss_rule_scheme import update_outbound_rules, init_inbound_rules, init_outbound_rules, msg_clear_all_outbound, ss_process_policy_change
from supersets import SuperSets
        self.init_vnh_assignment()

        rule_msgs = init_inbound_rules(self.id, self.policies,
                                        self.supersets, final_switch)
        self.logger.debug("Rule Messages INBOUND:: "+json.dumps(rule_msgs))

        rule_msgs2 = init_outbound_rules(self, self.id, self.policies,
                                        self.supersets, final_switch)
        self.logger.debug("Rule Messages OUTBOUND:: "+json.dumps(rule_msgs2))

        if 'changes' in rule_msgs2:
            if 'changes' not in rule_msgs:
                rule_msgs['changes'] = []
            rule_msgs['changes'] += rule_msgs2['changes']

        #TODO: Initialize Outbound Policies from RIB
        self.logger.debug("Rule Messages:: "+json.dumps(rule_msgs))
        if 'changes' in rule_msgs:
            self.dp_queued.extend(rule_msgs["changes"])


    def push_dp(self):
        '''
        (1) Check if there are any policies queued to be pushed
        (2) Send the queued policies to reference monitor
        '''

        self.logger.debug("Pushing current flow mod queue:")

        # it is crucial that dp_queued is traversed chronologically

# Path: xctrl/flowmodmsg.py
# class FlowModMsgBuilder(object):
#     def __init__(self, participant, key):
#         self.participant = participant
#         self.key = key
#         self.flow_mods = []
# 
#     def add_flow_mod(self, mod_type, rule_type, priority, match, action, cookie = None):
#         if cookie is None:
#             cookie = (len(self.flow_mods)+1, 65535)
# 
#         fm = {
#                "cookie": cookie,
#                "mod_type": mod_type,
#                "rule_type": rule_type,
#                "priority": priority,
#                "match": match,
#                "action": action
#              }
# 
#         self.flow_mods.append(fm)
# 
#         return cookie
# 
#     def delete_flow_mod(self, mod_type, rule_type, cookie, cookie_mask):
#         fm = {
#             "cookie": (cookie, cookie_mask),
#             "mod_type": mod_type,
#             "rule_type": rule_type,
#         }
# 
#         self.flow_mods.append(fm)
# 
#     def get_msg(self):
#         msg = {
#                 "auth_info": {
#                                "participant" : self.participant,
#                                "key" : self.key
#                              },
#                 "flow_mods": self.flow_mods
#               }
# 
#         return msg


# Path: pctrl/participant_controller.py
import argparse
import atexit
import json
import os
import time
import sys
import util.log
import pprint
from multiprocessing.connection import Listener, Client
from signal import signal, SIGTERM
from sys import exit
from threading import RLock, Thread
from xctrl.flowmodmsg import FlowModMsgBuilder
from lib import PConfig
from peer import BGPPeer
from ss_lib import vmac_part_port_match
from ss_rule_scheme import update_outbound_rules, init_inbound_rules, init_outbound_rules, msg_clear_all_outbound, ss_process_policy_change
from supersets import SuperSets

        self.init_vnh_assignment()

        rule_msgs = init_inbound_rules(self.id, self.policies,
                                        self.supersets, final_switch)
        self.logger.debug("Rule Messages INBOUND:: "+json.dumps(rule_msgs))

        rule_msgs2 = init_outbound_rules(self, self.id, self.policies,
                                        self.supersets, final_switch)
        self.logger.debug("Rule Messages OUTBOUND:: "+json.dumps(rule_msgs2))

        if 'changes' in rule_msgs2:
            if 'changes' not in rule_msgs:
                rule_msgs['changes'] = []
            rule_msgs['changes'] += rule_msgs2['changes']

        #TODO: Initialize Outbound Policies from RIB
        self.logger.debug("Rule Messages:: "+json.dumps(rule_msgs))
        if 'changes' in rule_msgs:
            self.dp_queued.extend(rule_msgs["changes"])


    def push_dp(self):
        '''
        (1) Check if there are any policies queued to be pushed
        (2) Send the queued policies to reference monitor
        '''

        self.logger.debug("Pushing current flow mod queue:")

        # it is crucial that dp_queued is traversed chronologically

        fm_builder = FlowModMsgBuilder(self.id, self.refmon_client.key)