# ToUpload/parsers/parse_block_header.py
# -*- coding: utf-8 -*-
from lxml import etree
import os

# Importar desde las utilidades del parser
from .parser_utils import ns, get_multilingual_text


def parse_block_header_from_xml(xml_filepath):
    """
    Extrae información del header del bloque desde un archivo XML de TIA Portal.

    Args:
        xml_filepath (str): Ruta al archivo XML

    Returns:
        dict: Diccionario con información del bloque:
        {
            'block_type': 'FC' | 'FB' | 'DB' | 'UDT' | 'PlcTagTable',
            'block_number': str | None,
            'block_name': str | None,
            'programming_language': str | None
        }
    """
    if not os.path.exists(xml_filepath):
        return None

    try:
        tree = etree.parse(xml_filepath)
        root = tree.getroot()

        # Buscar diferentes tipos de bloques
        block_info = {
            "block_type": None,
            "block_number": None,
            "block_name": None,
            "programming_language": None,
        }

        # 1. Function (FC)
        fc_node = root.find(".//SW.Blocks.FC")
        if fc_node is not None:
            block_info["block_type"] = "FC"
            block_info.update(_extract_common_attributes(fc_node))
            return block_info

        # 2. Function Block (FB)
        fb_node = root.find(".//SW.Blocks.FB")
        if fb_node is not None:
            block_info["block_type"] = "FB"
            block_info.update(_extract_common_attributes(fb_node))
            return block_info

        # 3. Organization Block (OB)
        ob_node = root.find(".//SW.Blocks.OB")
        if ob_node is not None:
            block_info["block_type"] = "OB"
            block_info.update(_extract_common_attributes(ob_node))
            return block_info

        # 4. Data Block (DB) - Global
        db_node = root.find(".//SW.Blocks.GlobalDB")
        if db_node is not None:
            block_info["block_type"] = "GlobalDB"
            block_info.update(_extract_common_attributes(db_node))
            return block_info

        # 5. Data Block (DB) - Instance
        idb_node = root.find(".//SW.Blocks.InstanceDB")
        if idb_node is not None:
            block_info["block_type"] = "InstanceDB"
            block_info.update(_extract_common_attributes(idb_node))
            return block_info

        # 6. User Defined Type (UDT)
        udt_node = root.find(".//SW.Types.PlcStruct")
        if udt_node is not None:
            block_info["block_type"] = "PlcUDT"
            block_info.update(_extract_common_attributes(udt_node))
            return block_info

        # 7. Tag Table
        tag_table_node = root.find(".//SW.Tags.PlcTagTable")
        if tag_table_node is not None:
            block_info["block_type"] = "PlcTagTable"
            block_info.update(_extract_common_attributes(tag_table_node))
            return block_info

        return None

    except Exception as e:
        print(f"Error parsing block header from {xml_filepath}: {e}")
        return None


def _extract_common_attributes(block_node):
    """
    Extrae atributos comunes de un nodo de bloque.

    Args:
        block_node: Nodo XML del bloque

    Returns:
        dict: Diccionario con atributos extraídos
    """
    attributes = {}

    # Buscar AttributeList
    attr_list = block_node.find("AttributeList")
    if attr_list is not None:
        # Nombre del bloque
        name_elem = attr_list.find("Name")
        if name_elem is not None:
            attributes["block_name"] = name_elem.text

        # Número del bloque
        number_elem = attr_list.find("Number")
        if number_elem is not None:
            attributes["block_number"] = str(number_elem.text)

        # Lenguaje de programación
        lang_elem = attr_list.find("ProgrammingLanguage")
        if lang_elem is not None:
            attributes["programming_language"] = lang_elem.text

    return attributes


def generate_block_header_comment(block_info):
    """
    Genera el comentario de header del bloque basado en la información extraída.

    Args:
        block_info (dict): Información del bloque extraída del XML

    Returns:
        str: Línea de comentario del header (ej: "// FC1032")
    """
    if not block_info or not block_info.get("block_type"):
        return None

    block_type = block_info["block_type"]
    block_number = block_info.get("block_number")

    # Mapear tipos de bloque a abreviaciones
    type_mapping = {
        "FC": "FC",
        "FB": "FB",
        "OB": "OB",
        "GlobalDB": "DB",
        "InstanceDB": "DB",
        "PlcUDT": "UDT",
        "PlcTagTable": "TAG",
    }

    abbreviated_type = type_mapping.get(block_type, block_type)

    if block_number:
        return f"// {abbreviated_type}{block_number}"
    else:
        return f"// {abbreviated_type}"


# Función de conveniencia para uso directo
def get_block_header_comment_from_xml(xml_filepath):
    """
    Función de conveniencia que extrae la información del bloque y genera el comentario de header.

    Args:
        xml_filepath (str): Ruta al archivo XML

    Returns:
        str | None: Comentario de header (ej: "// FC1032") o None si no se pudo extraer
    """
    block_info = parse_block_header_from_xml(xml_filepath)
    if block_info:
        return generate_block_header_comment(block_info)
    return None


if __name__ == "__main__":
    # Ejemplo de uso para testing
    import sys

    if len(sys.argv) > 1:
        xml_file = sys.argv[1]
        header = get_block_header_comment_from_xml(xml_file)
        print(f"Header for {xml_file}: {header}")
    else:
        print("Usage: python parse_block_header.py <xml_file>")
