#!/usr/bin/env python3
import sys
import xml.etree.ElementTree as ET
import os
import re

def remove_namespaces(xml_string):
    # 1) Entferne alle xmlns-Definitionen (\" oder ')
    xml_string = re.sub(r'\sxmlns(:\w+)?=(["\']).*?\2', '', xml_string, flags=re.DOTALL)

    # 2) Entferne Namespace-Präfixe aus Elementnamen: <ns:tag -> <tag, </ns:tag -> </tag
    xml_string = re.sub(r'<(/?)[A-Za-z0-9_\-]+:', r'<\1', xml_string)

    # 3) Entferne Namespace-Präfixe aus Attributnamen: ns:attr="..." -> attr="..."
    xml_string = re.sub(r'(\s)[A-Za-z0-9_\-]+:([A-Za-z0-9_\-]+=)', r'\1\2', xml_string)

    return xml_string


def bmk_prefix(bmk):
    """Gibt den Teil vor dem Doppelpunkt zurück."""
    if ":" in bmk:
        return bmk.split(":", 1)[0]
    return bmk

def safe_int(value):
    try:
        return int(float(value))
    except:
        return 0

def assign_new_numbers(sorted_klemmen):
    """
    Erwartet eine Liste von Tupeln
      (element, original_bmk, seite, x_position, y_position)
    und gibt zwei Listen zurück:
      - new_bmk_list: neue BMK-Labels
      - new_numbers: der Teil nach dem Doppelpunkt
    """
    new_bmk_list = []
    new_numbers = []
    prefix_counts = {}
    for _, original_bmk, *_ in sorted_klemmen:
        if ":" in original_bmk:
            prefix, rest = [s.strip() for s in original_bmk.split(":", 1)]
            try:
                int(rest)
                prefix_counts[prefix] = prefix_counts.get(prefix, 0) + 1
                new_num = prefix_counts[prefix]
                new_bmk = f"{prefix}:{new_num}"
                new_bmk_list.append(new_bmk)
                new_numbers.append(str(new_num))
            except ValueError:
                new_bmk_list.append(original_bmk)
                new_numbers.append(rest)
        else:
            new_bmk_list.append(original_bmk)
            new_numbers.append("")
    return new_bmk_list, new_numbers


def update_qet_file(input_file, output_file):
    try:
        with open(input_file, "r", encoding="utf-8") as f:
            xml_data = f.read()
        xml_data = remove_namespaces(xml_data)
        root = ET.fromstring(xml_data)
    except Exception as e:
        print(f"Fehler beim Parsen der Datei '{input_file}': {e}")
        sys.exit(1)
    
    # Klemmen sammeln mit neuem Filter: terminal_type vorhanden und Label nicht leer
    klemmen_items = []
    for diagram in root.findall(".//diagram"):
        seite = diagram.get("order", "").strip()
        for elem in diagram.findall(".//element"):
            # Filter: nur Elemente mit properties/element_type und terminal_type
            prop = elem.find("properties/element_type")
            if prop is None or not prop.get("terminal_type"):
                continue
            # Label auslesen
            bmk = ""
            infos = elem.find("elementInformations")
            if infos is not None:
                for info in infos.findall("elementInformation"):
                    if info.get("name", "").lower() == "label" and info.text:
                        bmk = info.text.strip()
                        break
            if not bmk:
                continue
            # Koordinaten
            x_position = elem.get("x", "").strip()
            y_position = elem.get("y", "").strip()
            klemmen_items.append((elem, bmk, seite, x_position, y_position))

    # Sortieren
    sorted_items = sorted(
        klemmen_items,
        key=lambda item: (
            bmk_prefix(item[1]).lower(),
            safe_int(item[2]),
            safe_int(item[3]),
            safe_int(item[4])
        )
    )

    # Neue Nummern zuweisen
    new_bmk_list, new_numbers = assign_new_numbers(sorted_items)
    
    # Labels und machine_manufacturer_reference aktualisieren
    for idx, (elem_obj, _, *_ ) in enumerate(sorted_items):
        new_bmk = new_bmk_list[idx]
        new_ref = new_bmk.split(":", 1)[1].strip() if ":" in new_bmk else ""
        infos = elem_obj.find("elementInformations")
        if infos is not None:
            for info in infos.findall("elementInformation"):
                name = info.get("name", "").lower()
                if name == "label":
                    info.text = new_bmk
                elif name == "machine_manufacturer_reference":
                    info.text = new_ref

    # XML speichern
    try:
        tree = ET.ElementTree(root)
        tree.write(output_file, encoding="utf-8", xml_declaration=True)
        print(f"Datei erfolgreich aktualisiert und gespeichert in '{output_file}'")
    except Exception as e:
        print(f"Fehler beim Schreiben der aktualisierten Datei: {e}")

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Verwendung: python3 Update_Klemmen.py <Input-QET-Datei> <Output-QET-Datei>")
        sys.exit(1)
    update_qet_file(sys.argv[1], sys.argv[2])

