import re
import xml.etree.ElementTree as ET # nosec B405
import lxml  
from ..constants import TIMEOUT_MS, WMS_NAMESPACES
from ..utils import FilterUtils, NetworkUtils

expr = re.compile(r"\{{1}.*\}{1}")

def getQueryableLayersFromWMS(wmsUrl):
    """Lista dostępnych warstw z usługi WMS"""

    PARAMS = {
        'SERVICE': 'WMS',
        'request': 'GetCapabilities',
    }
    network_utils = NetworkUtils()
    is_success, result = network_utils.fetchContent(wmsUrl, params=PARAMS, timeout_ms=TIMEOUT_MS * 2)

    if not is_success:
        return False, result

    content = result
    queryableLayers = []

    try:
        parser = lxml.etree.XMLParser(
                    resolve_entities=False,  # Prevent XXE
                    no_network=True,         # Disable network access
                    recover=False            # Avoid silent error recovery
                )
        
        root = ET.fromstring(content, parser=parser) # nosec B314
        for layerET in root.findall('.//xmlns:Layer[@queryable="1"]', WMS_NAMESPACES):
            nameET = layerET.find('./xmlns:Name', WMS_NAMESPACES)
            if nameET is not None:
                queryableLayers.append(nameET.text)
                
        queryableLayers = FilterUtils.removeDuplicatesFromListOfDicts(queryableLayers)
        
        return True, queryableLayers
        
    except ET.ParseError:
        return False, "Serwer zwrócił dane w niepoprawnym formacie (oczekiwano XML)."
    except Exception as e:
        return False, f"Błąd pobierania warstw WMS: {str(e)}"


def getWmsObjects(request_response):
    if not request_response[0]:
        return None
    req_elements = expr.findall(request_response[1])
    req_list = []
    for req_element in req_elements:
        element = req_element.strip("{").strip("}").split(',')
        attributes = {}
        for el in element:
            item = el.strip().split(':')
            key = item[0].strip('"')
            val = item[1].strip('"')
            if len(item) > 2:
                val = ":".join(item[1:]).strip('"')
            attributes[key] = val
        req_list.append(attributes)
    return FilterUtils.removeDuplicatesFromListOfDicts(req_list)
