<filename>src/genie/libs/parser/nxos/show_object_group.py
"""show_object_group.py

NXOS parsers for the following show commands:
    * 'show object-group'
    * 'show object-group {object-group}'
"""

# Python
import re

# Metaparser
from genie.metaparser import MetaParser
from genie.metaparser.util.schemaengine import Any, Optional, Or

# parser utils
from genie.libs.parser.utils.common import Common

# ========================================================
# Schema for:
#    * 'show object-group'
#    * 'show object-group {object-group}'
# ========================================================
class ShowObjectGroupSchema(MetaParser):
    """ Schema for:
        * 'show object-group'
        * 'show object-group {object-group}'
    """
    schema = {
        'group_type': { # 100=IPv4, 101=IPv6, 102=Protocol 
            Any(): {
                'group_name': {
                    Any(): {
                        Optional('seqno'): {
                            Any(): {
                                Optional('net_ip'): str,
                                Optional('net_ipv6'): str,
                                Optional('hostaddr'): str,
                                Optional('port_range'): str,
                                Optional('port_op'): str,
                                Optional('port0_num'): str,
                                Optional('port1_num'): str,
                                Optional('port2_num'): str,
                            }
                        }
                    }
                }
            }
        }
    }

class ShowObjectGroup(ShowObjectGroupSchema):
    """Parser for show object-group on NXOS
    parser class - implements detail parsing mechanisms for cli output
    """
    cli_command = 'show object-group'

    def cli(self, output=None):
        if output is None:
            out = self.device.execute(self.cli_command)
        else:
            out = output
        result_dict = {}

        # Defines the regex for the first line of device output, which is:
        # IPv4 address object-group GLOBAL_BE_DB_NETWORKS
        # Protocol port object-group auto_test_tcp
        p1 = re.compile(
            r'^(?P<group_type>(\S+)) +(address|port) +object-group +(?P<group_name>(\S+))$')

        # 10 2001:558:5000::/36
        p2 = re.compile(r'^(?P<seqno>(\S+)) +(?P<net_ip>(\S+))$')

        # 10 host 10.71.3.253
        p3 = re.compile(
            r'^(?P<seqno>(\S+)) +host +(?P<net_ip>(\S+))$')

        # 10 eq 23
        p4 = re.compile(
            r'^(?P<seqno>(\S+)) +(?P<port_op>(\S+)) +(?P<port0_num>(\S+))$')

        # 20 range 5666 - 5667
        p5 = re.compile(
            r'^(?P<seqno>(\S+)) +(?P<port_range>(\S+)) +(?P<port1_num>(\S+)) +- +(?P<port2_num>(\S+))$')

        

        # Defines the "for" loop, to pattern match each line of output
        for line in out.splitlines():
            line = line.strip()

            # Processes the matched patterns for the first line of output
            # IPv4 address object-group GLOBAL_BE_DB_NETWORKS
            m = p1.match(line)
            if m:
                group = m.groupdict()
                group_type = group['group_type']
                group_name = group['group_name']
                group_dict = result_dict.\
                    setdefault('group_type', {}).\
                        setdefault(group_type, {}).\
                            setdefault('group_name', {}).\
                                setdefault(group_name, {})
                continue
            
            #  10 10.72.11.0/24
            m = p2.match(line)
            if m:
                group = m.groupdict()
                seqno = group['seqno']
                net_ip = group['net_ip']
                group_object_dict = group_dict.\
                    setdefault('seqno', {}).\
                        setdefault(seqno, {})
                group_object_dict['net_ip']=net_ip
                continue

            m = p3.match(line)
            if m:
                group = m.groupdict()
                seqno = group['seqno']
                net_ip = group['net_ip']
                group_object_dict = group_dict.\
                    setdefault('seqno', {}).\
                        setdefault(seqno, {})
                group_object_dict['net_ip']=net_ip
                continue

            m = p4.match(line)
            if m:
                group = m.groupdict()
                seqno = group['seqno']
                port_op = group['port_op']
                port0_num = group['port0_num']
                group_object_dict = group_dict.\
                    setdefault('seqno', {}).\
                        setdefault(seqno, {})
                group_object_dict['port_op']=port_op
                group_object_dict['port0_num']=port0_num
                
            m = p5.match(line)
            if m:
                group = m.groupdict()
                seqno = group['seqno']
                port_range = group['port_range']
                port1_num = group['port1_num']
                port2_num = group['port2_num']
                group_object_dict = group_dict.\
                    setdefault('seqno', {}).\
                        setdefault(seqno, {})
                group_object_dict['port_range']=port_range
                group_object_dict['port1_num']=port1_num
                group_object_dict['port2_num']=port2_num

        return result_dict
 