# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


"""
#Method Name: parse

#Parameters:
    
    - xml_data: [ET.Element] Represents the XML data to be parsed.

# Functionality:

The parse function of the interfaces_mng class has the functionality to parse
an XML document represented by the xml_data parameter and extract specific 
information from the XML elements, namely the active interfaces with their name, 
type, ipv4 and ipv6 addresses in case they have.

To generate the template the following steps are performed:

1) An empty list called response is created to store the results of the analysis.

2) Iterate over the XML elements that match the pattern specified by the XPATH_PORTS 
expression. These elements represent management interfaces in the XML document.

3) For each  management interfaces:
A dictionary called interfaces_mng is initialized that will store the information extracted 
from the interfaces.The values of the relevant XML elements are extracted and added to
the dictionary.

#Return: 
List[Tuple[str, Dict[str, Any]]] The response list containing the tuples (path, dictionary) 
with the information extracted from the XML document interfaces is returned.

"""


import logging, lxml.etree as ET
from typing import Any, Dict, List, Tuple
from .Namespace import NAMESPACES
from .Tools import add_value_from_tag

LOGGER = logging.getLogger(__name__)

XPATH_PORTS = "//oci:interfaces/oci:interface"
XPATH_SUBINTERFACES = ".//oci:subinterfaces/oci:subinterface"
XPATH_IPV4ADDRESSES = ".//ociip:ipv4/ociip:addresses/ociip:address"
XPATH_IPV6ADDRESSES = ".//ociip:ipv6/ociip:addresses/ociip:address"

def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
    response = []
    LOGGER.debug("Interfaces_mngPrueba")
    
    for xml_interface_mng in xml_data.xpath(XPATH_PORTS, namespaces=NAMESPACES):
        LOGGER.info('xml_component xml_interfaces_mng = {:s}'.format(str(ET.tostring(xml_interface_mng))))
        interfaces_mng = {}
        
        interface_enabled = xml_interface_mng.find('oci:config/oci:enabled', namespaces=NAMESPACES)
        if interface_enabled == None:
            interface_enabled = xml_interface_mng.find('oci:state/oci:enabled', namespaces=NAMESPACES)
        if interface_enabled == None: continue
        if 'false' in interface_enabled or 'false' in interface_enabled.text: continue

        interface_name = xml_interface_mng.find('oci:name', namespaces=NAMESPACES)
        if interface_name is None or interface_name.text is None: continue
        add_value_from_tag(interfaces_mng, 'name', interface_name)
              
        interface_type = xml_interface_mng.find('oci:config/oci:type', namespaces=NAMESPACES)
        if interface_type is None:
            interface_type = xml_interface_mng.find('oci:state/oci:type', namespaces=NAMESPACES)         
        if interface_type is None: continue
        interface_type.text = interface_type.text.replace('ianaift:','')
        add_value_from_tag(interfaces_mng, 'type', interface_type)
        
        for xml_subinterface in xml_interface_mng.xpath(XPATH_SUBINTERFACES, namespaces=NAMESPACES):
            for xml_ipv4_address in xml_subinterface.xpath(XPATH_IPV4ADDRESSES, namespaces=NAMESPACES):
                address_ipv4 = xml_ipv4_address.find('ociip:state/ociip:ip', namespaces=NAMESPACES)
                if not address_ipv4 is None:
                    add_value_from_tag(interfaces_mng, 'ipv4', address_ipv4)

            for xml_ipv6_address in xml_subinterface.xpath(XPATH_IPV6ADDRESSES, namespaces=NAMESPACES):
                address_ipv6 = xml_ipv6_address.find('ociip:state/ociip:ip', namespaces=NAMESPACES)
                if not address_ipv6 is None:
                    add_value_from_tag(interfaces_mng, 'ipv6', address_ipv6)
        if not 'ipv4' in interfaces_mng and not 'ipv6' in interfaces_mng: 
            if 'ip' in interfaces_mng['type'] or 'Loopback' in interfaces_mng['type']: continue
        response.append(('/interfaces_mng/{:s}'.format(interfaces_mng['name']), interfaces_mng))
                
    return response
