import logging

from oftest import config
import oftest.base_tests as base_tests
import ofp
import time
from oftest.testutils import *

from ncclient import manager
import ncclient

OFDPA_GROUP_TYPE_SHIFT=28
OFDPA_VLAN_ID_SHIFT   =16
OFDPA_TUNNEL_ID_SHIFT =12
OFDPA_TUNNEL_SUBTYPE_SHIFT=10

#VLAN_TABLE_FLAGS
VLAN_TABLE_FLAG_ONLY_UNTAG=1
VLAN_TABLE_FLAG_ONLY_TAG  =2
VLAN_TABLE_FLAG_ONLY_BOTH =3

def encode_l2_interface_group_id(vlan, id):
    return id + (vlan << OFDPA_VLAN_ID_SHIFT)

def encode_l2_rewrite_group_id(id):
    return id + (1 << OFDPA_GROUP_TYPE_SHIFT)

def encode_l3_unicast_group_id(id):
    return id + (2 << OFDPA_GROUP_TYPE_SHIFT)

def encode_l2_mcast_group_id(vlan, id):
    return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)

def encode_l2_flood_group_id(vlan, id):
    return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
    
def encode_l3_interface_group_id(id):
    return id + (5 << OFDPA_GROUP_TYPE_SHIFT)

def encode_l3_mcast_group_id(vlan, id):
    return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)

def encode_l3_ecmp_group_id(id):
    return id + (7 << OFDPA_GROUP_TYPE_SHIFT)

def encode_l2_overlay_group_id(tunnel_id, subtype, index):
    tunnel_id=tunnel_id&0xffff #16 bits
    subtype = subtype&3        #2 bits
    index = index & 0x3f       #10 bits
    return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)

def add_l2_interface_grouop(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
    # group table
    # set up untag groups for each port
    group_id_list=[]
    msgs=[]
    for of_port in ports:
        # do stuff
        group_id = encode_l2_interface_group_id(vlan_id, of_port)
        group_id_list.append(group_id)
        if is_tagged:
            actions = [
                ofp.action.output(of_port),
            ]        
        else:
            actions = [
                ofp.action.pop_vlan(),
                ofp.action.output(of_port),
            ]

        buckets = [
            ofp.bucket(actions=actions),
        ]

        request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
                                        group_id=group_id,
                                        buckets=buckets
                                       )
        ctrl.message_send(request)
        msgs.append(request)

        if send_barrier:
            do_barrier(ctrl)
 
    return group_id_list, msgs

def add_one_l2_interface_grouop(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
    # group table
    # set up untag groups for each port
    group_id = encode_l2_interface_group_id(vlan_id, port)

    if is_tagged:
        actions = [
            ofp.action.output(port),
        ]        
    else:
        actions = [
            ofp.action.pop_vlan(),
            ofp.action.output(port),
        ]

    buckets = [
        ofp.bucket(actions=actions),
    ]

    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)

    if send_barrier:
        do_barrier(ctrl)
 
    return group_id, request
    
def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
    buckets=[]
    for of_port in ports:
        group_id = encode_l2_interface_group_id(vlanid, of_port)
        action=[ofp.action.group(group_id)]
        buckets.append(ofp.bucket(actions=action))

    group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request

def add_l2_flood_group(ctrl, ports, vlanid, id):
    buckets=[]
    for of_port in ports:
        group_id = encode_l2_interface_group_id(vlanid, of_port)
        action=[ofp.action.group(group_id)]
        buckets.append(ofp.bucket(actions=action))

    group_id =encode_l2_flood_group_id(vlanid, id)
    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request

def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
    group_id = encode_l2_interface_group_id(vlanid, port)

    action=[]
    if src_mac is not None:
        action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))

    if dst_mac is not None:
        action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))

    action.append(ofp.action.group(group_id))
    
    buckets = [ofp.bucket(actions=action)]

    group_id =encode_l2_rewrite_group_id(id)
    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request
    
def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac):
    group_id = encode_l2_interface_group_id(vlanid, port)

    action=[]
    if src_mac is not None:
        action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))

    if dst_mac is not None:
        action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))

    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
        
    action.append(ofp.action.group(group_id))
    
    buckets = [ofp.bucket(actions=action)]

    group_id =encode_l3_unicast_group_id(id)
    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request
    
def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
    group_id = encode_l2_interface_group_id(vlanid, port)

    action=[]
    action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))       
    action.append(ofp.action.group(group_id))
    
    buckets = [ofp.bucket(actions=action)]

    group_id =encode_l3_interface_group_id(id)
    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request

def add_l3_ecmp_group(ctrl, id, l3_ucast_groups):
    buckets=[]
    for group in l3_ucast_groups:
        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))

    group_id =encode_l3_ecmp_group_id(id)
    request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request
        
def add_l3_mcast_group(ctrl, vid,  mcast_group_id, groups_on_buckets):
    buckets=[]
    for group in groups_on_buckets:
        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
    
    group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request

def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
    buckets=[]
    for port in ports:
        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))

    group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request

def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
    buckets=[]
    for port in ports:
        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))

    group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request

def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
    buckets=[]
    for port in ports:
        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))

    group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request

def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
    buckets=[]
    for port in ports:
        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))

    group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request
	
def add_port_table_flow(ctrl, is_overlay=True):
    match = ofp.match()

    if is_overlay == True:
       match.oxm_list.append(ofp.oxm.in_port(0x10000))
       NEXT_TABLE=50
    else:
       match.oxm_list.append(ofp.oxm.in_port(0))
       NEXT_TABLE=10       

    request = ofp.message.flow_add(
		table_id=0,
		cookie=42,
		match=match,
		instructions=[
		  ofp.instruction.goto_table(NEXT_TABLE)
		],
		priority=0)
    logging.info("Add port table, match port %lx" % 0x10000)
    ctrl.message_send(request)
    
    

def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
    # table 10: vlan
    # goto to table 20
    msgs=[]
    for of_port in ports:
        if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
            match = ofp.match()
            match.oxm_list.append(ofp.oxm.in_port(of_port))
            match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
            request = ofp.message.flow_add(
                table_id=10,
                cookie=42,
                match=match,
                instructions=[
                  ofp.instruction.goto_table(20)
                ],
                priority=0)
            logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
            ctrl.message_send(request)
            
        if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
            match = ofp.match()
            match.oxm_list.append(ofp.oxm.in_port(of_port))
            match.oxm_list.append(ofp.oxm.vlan_vid(0))
            request = ofp.message.flow_add(
                table_id=10,
                cookie=42,
                match=match,
                instructions=[
                  ofp.instruction.apply_actions(
                    actions=[
                      ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
                    ]
                  ),
                  ofp.instruction.goto_table(20)
                ],
                priority=0)
            logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
            ctrl.message_send(request)
            msgs.append(request)

    if send_barrier:
        do_barrier(ctrl)

    return msgs

def add_one_vlan_table_flow(ctrl, of_port, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
    # table 10: vlan
    # goto to table 20
    if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(of_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
        request = ofp.message.flow_add(
            table_id=10,
            cookie=42,
            match=match,
            instructions=[
              ofp.instruction.goto_table(20)
            ],
            priority=0)
        logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
        ctrl.message_send(request)
        
    if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(of_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(0))
        request = ofp.message.flow_add(
            table_id=10,
            cookie=42,
            match=match,
            instructions=[
              ofp.instruction.apply_actions(
                actions=[
                  ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
                ]
              ),
              ofp.instruction.goto_table(20)
            ],
            priority=0)
        logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
        ctrl.message_send(request)

    if send_barrier:
        do_barrier(ctrl)

    return request
    
def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
    match = ofp.match()
    if dst_mac!=None:
        match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))

    match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))

    request = ofp.message.flow_add(
            table_id=50,
            cookie=42,
            match=match,
            instructions=[
                ofp.instruction.write_actions(
                    actions=[
                        ofp.action.group(group_id)]),
                    ofp.instruction.goto_table(60)
                ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000) 

    logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
    ctrl.message_send(request)

    if send_barrier:
        do_barrier(ctrl)   

    return request        

def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
    match = ofp.match()
    if dst_mac!=None:
        match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))

    match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
    if is_group == True:
        actions=[ofp.action.group(group_id)]
    else:
        actions=[ofp.action.output(group_id)]

    request = ofp.message.flow_add(
            table_id=50,
            cookie=42,
            match=match,
            instructions=[
                ofp.instruction.write_actions(
                    actions=actions),
                    ofp.instruction.goto_table(60)
                ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000) 

    logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
    ctrl.message_send(request)

    if send_barrier:
        do_barrier(ctrl)   

    return request        
    
def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, send_barrier=False):
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
    if dst_mac[0]&0x01 == 0x01:
       match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
       goto_table=40
    else:
       match.oxm_list.append(ofp.oxm.in_port(in_port))    
       match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
       match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
       goto_table=30

    request = ofp.message.flow_add(
            table_id=20,
            cookie=42,
            match=match,
            instructions=[
                    ofp.instruction.goto_table(goto_table)
                ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1) 

    logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
    ctrl.message_send(request)

    if send_barrier:
        do_barrier(ctrl)   

    return request    
    
def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, send_barrier=False):
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
    if mask!=0:
        match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
    else:
        match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))

    request = ofp.message.flow_add(
            table_id=30,
            cookie=42,
            match=match,
            instructions=[
                    ofp.instruction.write_actions(
                        actions=[ofp.action.group(action_group_id)]),
                    ofp.instruction.goto_table(60)
                ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1) 

    logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
    ctrl.message_send(request)

    if send_barrier:
        do_barrier(ctrl)   

    return request        
        
def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.eth_type(0x0800))
    match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id))    
    if src_ip_mask!=0:
        match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
    else:
        match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
        
    match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
    
    request = ofp.message.flow_add(
            table_id=40,
            cookie=42,
            match=match,
            instructions=[
                    ofp.instruction.write_actions(
                        actions=[ofp.action.group(action_group_id)]),
                    ofp.instruction.goto_table(60)
                ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1) 

    logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
    ctrl.message_send(request)

    if send_barrier:
        do_barrier(ctrl)   

    return request            
       
def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):  
    """
    Command Example:
    of-agent vtap 10001 ethernet 1/1 vid 1
    of-agent vtp 10001 vni 10
    """
    if vlan != 0:
        config_vtap_xml="""
        <config>
            <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
                <id>capable-switch-1</id>
                <resources>
                    <port xc:operation="OPERATION">
                        <resource-id >LPORT</resource-id>     
                        <features>
                            <current>
                              <rate>10Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>      
                            </current>
                            <advertised>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </advertised>    
                            <supported>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </supported> 
                            <advertised-peer>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </advertised-peer>        
                        </features>
                        <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
                            <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
                            <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
                            <ofdpa10:vni>VNID</ofdpa10:vni>
                        </ofdpa10:vtap>
                    </port> 
              </resources>
              <logical-switches>
                  <switch>
                    <id>DATAPATH_ID</id>
                    <datapath-id>DATAPATH_ID</datapath-id>
                    <resources>
                      <port xc:operation="OPERATION">LPORT</port>
                    </resources>
                  </switch>
              </logical-switches>
            </capable-switch>
          </config>
        """    
    else:
        config_vtap_xml="""
        <config>
            <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
                <id>capable-switch-1</id>
                <resources>
                    <port xc:operation="OPERATION">
                        <resource-id >LPORT</resource-id>     
                        <features>
                            <current>
                              <rate>10Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>      
                            </current>
                            <advertised>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </advertised>    
                            <supported>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </supported> 
                            <advertised-peer>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </advertised-peer>        
                        </features>
                        <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
                            <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
                            <ofdpa10:vni>VNID</ofdpa10:vni>
                        </ofdpa10:vtap>
                    </port> 
              </resources>
              <logical-switches>
                  <switch>
                    <id>DATAPATH_ID</id>
                    <datapath-id>DATAPATH_ID</datapath-id>
                    <resources>
                      <port xc:operation="OPERATION">LPORT</port>
                    </resources>
                  </switch>
              </logical-switches>
            </capable-switch>
          </config>
        """        
    str_datapath_id_f= "{:016x}".format(dp_id)        
    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])	
    config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)      
    config_vtap_xml=config_vtap_xml.replace("LPORT", str(hex(lport)))         
    config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))       
    config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))     
    config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
    config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
    return config_vtap_xml
      
def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'): 
    """
    Command Example:
    of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
    of-agent vtp 10001 vni 10    
    """

    config_vtep_xml="""
        <config>
          <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
            <id>capable-switch-1</id>
            <resources>
             <port xc:operation="OPERATION">
               <resource-id>LPORT</resource-id>     
                 <features>
                   <current>
                     <rate>10Gb</rate>
                     <medium>fiber</medium>
                     <pause>symmetric</pause>      
                   </current>
                   <advertised>
                     <rate>10Gb</rate>
                     <rate>100Gb</rate>
                     <medium>fiber</medium>
                     <pause>symmetric</pause>
                   </advertised>    
                   <supported>
                     <rate>10Gb</rate>
                     <rate>100Gb</rate>
                     <medium>fiber</medium>
                     <pause>symmetric</pause>
                   </supported> 
                   <advertised-peer>
                     <rate>10Gb</rate>
                     <rate>100Gb</rate>
                     <medium>fiber</medium>
                     <pause>symmetric</pause>
                   </advertised-peer>        
                </features>
			  <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
				<ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
				<ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
				<ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
				<ofdpa10:vni>VNID</ofdpa10:vni>
				<ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
				<ofdpa10:ttl>TTL</ofdpa10:ttl>
			  </ofdpa10:vtep>
             </port> 
            </resources>
            <logical-switches>
                <switch>
                  <id>DATAPATH_ID</id>
                  <datapath-id>DATAPATH_ID</datapath-id>
                  <resources>
                    <port xc:operation="OPERATION">LPORT</port>
                  </resources>
                </switch>
            </logical-switches>
          </capable-switch>
        </config>  
    """
    str_datapath_id_f= "{:016x}".format(dp_id)        
    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])	
    config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)      
    config_vtep_xml=config_vtep_xml.replace("LPORT", str(hex(lport)))
    config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))            
    config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))                 
    config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))                      
    config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))                           
    config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))                           
    config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
    config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))		

    return config_vtep_xml   
      
def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'): 
    #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
    config_nexthop_xml="""
      <config>
          <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
            <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01"  xc:operation="OPERATION">
              <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
              <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
              <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
              <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
            </ofdpa10:next-hop>
          </of11-config:capable-switch>
      </config>
      """
    config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
    config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))   
    config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))   
    config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))   
    config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))	
    return config_nexthop_xml   

def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):  
    #of-agent vni 10 multicast 224.1.1.1 nexthop 20
    if mcast_ipv4!=None:    
        config_vni_xml="""
          <config>
              <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
                <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
                  <ofdpa10:id>VNID</ofdpa10:id>
                  <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
                  <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
                </ofdpa10:vni>
              </of11-config:capable-switch>
          </config>
          """   
        config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))   
        config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))             
    else:
        config_vni_xml="""
          <config>
              <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
                <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
                  <ofdpa10:id>VNID</ofdpa10:id>
                </ofdpa10:vni>
              </of11-config:capable-switch>
          </config>
          """   
          
    config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))            
    config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))	
    return config_vni_xml
	
def get_featureReplay(self):    
    req = ofp.message.features_request()
    res, raw = self.controller.transact(req)
    self.assertIsNotNone(res, "Did not receive a response from the DUT.")        
    self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
                 ("Unexpected packet type %d received in response to "
                  "OFPT_FEATURES_REQUEST") % res.type)
    return res		
	
def send_edit_config(switch_ip, xml, target='runing'):
    NETCONF_ACCOUNT="netconfuser"
    NETCONF_PASSWD="netconfuser"
    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
        try:
            m.edit_config(target='running', 
                      config=xml, 
                      default_operation='merge', 
                      error_option='stop-on-error')

        except Exception as e:
            logging.info("Fail to set xml %s", xml)
            return False

	#return m.get_config(source='running').data_xml
    return True

def send_delete_config(switch_ip, xml, target='runing'):
    NETCONF_ACCOUNT="netconfuser"
    NETCONF_PASSWD="netconfuser"
    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
        try:
            m.edit_config(target='running', 
                      config=xml, 
                      default_operation='delete', 
                      error_option='stop-on-error')

        except Exception as e:
            logging.info("Fail to set xml %s", xml)
            return False

	#return m.get_config(source='running').data_xml
    return True
    
def get_edit_config(switch_ip, target='runing'):
    NETCONF_ACCOUNT="netconfuser"
    NETCONF_PASSWD="netconfuser"
    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
	    print m.get_config(source='running').data_xml

        
def print_current_table_flow_stat(ctrl, table_id=0xff):
    stat_req=ofp.message.flow_stats_request()
    response, pkt = ctrl.transact(stat_req)
    if response == None:
        print "no response"
        return None
    print len(response.entries)
    for obj in response.entries:
        print "match ", obj.match
        print "cookie", obj.cookie
        print "priority", obj.priority
        print "idle_timeout", obj.idle_timeout
        print "hard_timeout", obj.hard_timeout
        #obj.actions
        print "packet count: %lx"%obj.packet_count