#!/usr/bin/env python3
"""Seed 4 new generic-validation IACE projects from their Grenzen documents.

Faithful limits_form reconstructed from the BP risk-assessment .docx files in
breakpilot-core/docs-src. Used to test pattern-engine genericity (no foreign-
domain nonsense) beyond the 2 existing ground truths (Kistenhub + Bremse).

Run from MacBook against macmini:8093 (TLS, self-signed -> verify off).
"""
import json
import ssl
import urllib.request

BASE = "https://macmini:8093/sdk/v1/iace"
TENANT = "9282a473-5c95-4b3a-bf78-0ecc0ec71d3e"
CTX = ssl.create_default_context()
CTX.check_hostname = False
CTX.verify_mode = ssl.CERT_NONE


def call(method, path, body=None):
    data = json.dumps(body).encode() if body is not None else None
    req = urllib.request.Request(BASE + path, data=data, method=method)
    req.add_header("Content-Type", "application/json")
    req.add_header("X-Tenant-ID", TENANT)
    try:
        with urllib.request.urlopen(req, context=CTX, timeout=120) as r:
            return r.status, json.loads(r.read().decode())
    except urllib.error.HTTPError as e:
        return e.code, e.read().decode()


MACHINES = [
    {
        "machine_name": "Kniehebelpresse (Kaltmassivumformung)",
        "machine_type": "mechanical_press",
        "manufacturer": "Eigenbau GmbH",
        "limits_form": {
            "general_description": "Die Anlage ist eine vollautomatische Kniehebelpresse (Kaltmassivumformung). Sie besteht aus Rohlings-Zufuehrung, Transferanlage zur Zufuehrung der Rohlinge in die Presse, der Kniehebelpresse selbst, einer vollstaendig in die Presse integrierten Schmieranlage, einer Absaugung, dem Abtransport der fertigen Teile (Eigenbau) und einer Schutzumhausung. Die Rohlinge werden automatisch zugefuehrt, vor Einbringung in die Presse gewendet und positioniert. In der Presse werden die Teile in 5 Schritten umgeformt; fuer jeden Schritt gibt es einen eigenen Werkzeugsatz. Die fertigen heissen Teile fallen auf ein Foerderband und werden in Kisten transportiert.",
            "intended_purpose": "Die Anlage dient der automatischen Kaltmassivumformung von metallischen Rohlingen.",
            "foreseeable_misuses": "Ueberschreiten zulaessiger Belastungsgrenzen. Verwendung ungeeigneter Rohlinge. Betrieb in explosionsgefaehrdeter Atmosphaere. Betrieb bei Austreten von Hydraulikoel, Schmierfluessigkeit oder Druckluft. Betrieb bei Rauchentwicklung oder ungewoehnlichen Geraeuschen. Bedienung ohne erforderliche persoenliche Schutzausruestung. Zugang zu abgesicherten Bereichen unter Umgehung der Sicherheitseinrichtungen.",
            "spatial_limits": "Aufzugsportal. Zugaenglicher Bereich der Zufuehrung. Presseninnenraum (Werkzeugeinbauraum), erreichbar ueber vordere Tuer. Presseninnenraum, erreichbar ueber hintere Tuer. Bereich um die Abfuehrbaender. Quetsch- und Scherstellen am Stoessel und an den Werkzeugsaetzen.",
            "temporal_limits": "Wartungsarbeiten gemaess Anleitungen der Lieferanten der jeweiligen Bauteile. Umruestung auf verschiedene Produkte.",
            "technical_data": "Nennkraft 20000 kN. Nennkraftweg vor U.T. 30 mm. Arbeitsvermoegen 400 kJ (vergroessert 600 kJ ab Hubzahl 16/min). Hubzahl 16-36/min. Stoesselhub 630 mm. Stoesselflaeche 1800x1000 mm. Tischflaeche 1800x1000 mm. 5 Stufen, Abstand 350 mm. Kippmoment max. 4500 kNm. Bauhoehe ueber Flur ca. +8600 mm, Fundamenttiefe ca. -5000 mm.",
            "electrical_interfaces": "Hauptstromkreis 400 V, 50 Hz. Steuerstromkreis 230 V Wechselspannung und 24 V Gleichspannung. Absauganlage-Motor 3,0 kW, 400 V. Elektrische Komponenten und Steuerung.",
            "mechanical_interfaces": "Rohlings-Zufuehrung ueber Aufzugsportal (Kisten ca. 3 m nach oben). Ruettelplatte. Foerderband zur Presse. Stoessel und Werkzeugsaetze. Abfuehrbaender. Bewegliche Teile mit Quetsch- und Scherstellen im Presseninnenraum.",
            "pneumatic_hydraulic_interfaces": "Hydraulikoel im System (Oelfangschalen unter dem Staenderdurchgang). Druckluft im System. Schmieranlage vollstaendig in die Presse integriert.",
            "software_interfaces": "Vollautomatische Steuerung der Zufuehrung, Bearbeitung und Abfuehrung.",
            "operating_conditions": "Zulaessige Umgebungstemperatur +5 bis +40 Grad C. Relative Luftfeuchte nicht betauend 30% bei 40 Grad C bis 95% bei 20 Grad C. Hoehenlage bis 1000 m ueber NN.",
            "operating_modes": "Betrieb vollautomatisch. Einrichten und Umruesten. Instandhaltung und Reinigung. Instandsetzung (Reparaturen).",
            "person_groups": "Bedienpersonal: eingewiesenes Personal ohne besondere Fachkenntnisse.",
            "qualification_requirements": "Bedienpersonal ist eingewiesenes Personal ohne besondere Fachkenntnisse, mit der Funktion der Anlage vertraut. Werkzeugwechsel sowie Instandhaltung und Instandsetzung werden in dieser Beurteilung nicht betrachtet.",
            "emergency_stop": "Not-Halt an der Bedieneinheit der Presse.",
            "malfunction_interventions": "",
            "other_limits": "Organisatorische Schutzmassnahme: Tragen von Sicherheitsschuhen, Gehoerschutz und Handschuhen in der Fertigungshalle (Handschuhe nur fuer Werker, nicht fuer Instandhaltung/Werkzeugwechsel).",
        },
    },
    {
        "machine_name": "EIGENBAU-Zelle (Arbeitstisch mit Roboterarm)",
        "machine_type": "robotics_cobot",
        "manufacturer": "Eigenbau GmbH",
        "limits_form": {
            "general_description": "Die EIGENBAU-Zelle ist ein Arbeitstisch mit integriertem Roboterarm zum Einsatz im industriellen Umfeld. Es werden zwei Ausfuehrungsvarianten betrachtet: nicht kollaborierender Betrieb (ein Sicherheitsscanner setzt den Roboterarm bei Annaeherung von Personen still) und kollaborierender Betrieb fuer nicht gefaehrliche Anwendungen. Der Roboterarm dient in erster Linie dem Bewegen von Teilen, insbesondere der Bestueckung von Maschinen, und kann abhaengig vom gewaehlten Werkzeug einfache Bearbeitungsvorgaenge selbst vornehmen.",
            "intended_purpose": "Die EIGENBAU-Zelle ist fuer die Bestueckung und Bedienung von Maschinen und Anlagen vorgesehen. Ergaenzend fuer die Variante kollaborierender Betrieb besteht die Moeglichkeit eines Betriebs im kollaborierenden Modus fuer nicht gefaehrliche Anwendungen.",
            "foreseeable_misuses": "Nutzung mit nicht ausreichend programmierten Grenzen fuer Kraft und Geschwindigkeit. Nutzung bei Anwendungen mit unzureichenden Reaktionszeiten der Sicherheitsfunktionen. Verwendung von Werkzeugen mit Nachlauf. Nutzung als Steighilfe. Betrieb ausserhalb der zulaessigen Betriebsparameter. Nutzung in potentiell explosionsgefaehrdeten Umgebungen. Nutzung mit fuer einen kollaborierenden Betrieb nicht geeigneten Werkzeugen oder Werkstuecken.",
            "spatial_limits": "Raum in Reichweite des Roboterarms. Oberflaeche des Tischs. Oberflaeche des Roboterarms. Bereich um das verwendete Werkzeug und Werkstueck. Quetsch- und Stossgefahr durch bewegliche Teile des Roboterarms.",
            "temporal_limits": "Die korrekte Arbeitsweise aller Sicherheitsfunktionen sollte mindestens einmal jaehrlich ueberprueft werden. Berechnete Betriebsdauer des Roboterarms: 35.000 h.",
            "technical_data": "Abmessungen max. 2000x800x1500 mm. Gewicht max. 500 kg. Traglast des Roboterarms 5 kg. Reichweite des Roboterarms 850 mm. Geschwindigkeit max. 180 Grad/s. Geschwindigkeit des Werkzeugs max. 1 m/s.",
            "electrical_interfaces": "Spannungsversorgung 230 V. Leistungsaufnahme max. 325 W. Schutzart IP.",
            "mechanical_interfaces": "Integrierter Roboterarm zum Bewegen von Teilen. Werkzeug und Werkstueck gemaess Betriebsanleitung. Bewegliche Teile des Roboterarms mit Quetsch- und Stossgefahr in Reichweite.",
            "pneumatic_hydraulic_interfaces": "Keine pneumatischen oder hydraulischen Schnittstellen.",
            "software_interfaces": "Programmierung des Roboterarms ueber einen in den Tisch integrierten Touchscreen. Sicherheitsscanner zur Personenerkennung in der nicht kollaborierenden Variante. Sicherheitsfunktionen zur Begrenzung von Kraft und Geschwindigkeit.",
            "operating_conditions": "Umgebungsbedingungen 0 bis 50 Grad C.",
            "operating_modes": "Betrieb im kollaborierenden oder nicht kollaborierenden Modus. Einrichten, Einlernen (Teachen) und Programmieren. Umruesten. Reinigung. Instandhaltung.",
            "person_groups": "Laien, eingewiesene Personen, Fachpersonal, Fachpersonal mit gesonderter Schulung durch den Hersteller.",
            "qualification_requirements": "Transport: Fachpersonal. Montage, Installation und Inbetriebnahme: Eingewiesene Personen. Einrichten, Teachen, Programmieren und Umruesten: Fachpersonal mit gesonderter Schulung. Betrieb und Reinigung: Eingewiesene Personen. Instandhaltung, Sichtpruefungen, Fehlersuche und Demontage: Fachpersonal.",
            "emergency_stop": "",
            "malfunction_interventions": "",
            "other_limits": "Es bestehen keine weiteren relevanten Grenzen.",
        },
    },
    {
        "machine_name": "Elektromotoren (Gleichstrom- und Asynchronmotoren)",
        "machine_type": "general_industry",
        "manufacturer": "Eigenbau GmbH",
        "limits_form": {
            "general_description": "Die Eigenbau GmbH stellt Gleichstrom- und Asynchronmotoren mit oder ohne integriertes Getriebe her. Die Motoren werden als Antriebe in Maschinen und Anlagen eingebaut.",
            "intended_purpose": "Einbau als Antrieb in Maschinen und Anlagen entsprechend den technischen Daten.",
            "foreseeable_misuses": "Betrieb unter Wasser. Betrieb in explosionsfaehiger Atmosphaere. Betrieb in aetzender Atmosphaere. Betrieb unter Schock- und Vibrationseinwirkung. Nutzung des Motors als Steighilfe. Nutzung ohne ausreichende Kuehlung oder in zu hoher Umgebungstemperatur. Nutzung ohne angeschlossene Uebertemperaturueberwachung. Automatischer Wiederanlauf nach Ausloesen des Thermoschalters. Fehlerhafte elektrische Installation, zum Beispiel nicht angeschlossener Schutzleiter.",
            "spatial_limits": "Gehaeuse (Stromschlag, Erhitzung). Elektrische Anschluesse. Bewegliche Teile des Motors.",
            "temporal_limits": "Lebensdauer 2.000 bis 20.000 Stunden. Wartungsintervalle gemaess Herstellerangaben.",
            "technical_data": "Spannungsversorgung 24 bis 400 V, Gleichstrom bzw. ein- oder dreiphasiger Wechselstrom. Nennleistung 4,3 W bis 562 W. Nenndrehzahl 1250 rpm bis 3800 rpm. Nennmoment 3,3 cNm bis 27 Nm. Schutzart IP 00 (offene Bauart) bis IP 65. Isolierstoffklasse B oder F.",
            "electrical_interfaces": "Energieversorgung 24 bis 400 V, Gleichstrom bzw. ein- oder dreiphasiger Wechselstrom. Anschluesse der Energieversorgung. Uebertemperaturueberwachung ueber Thermowiderstand oder Bimetallschalter. Schutzleiter.",
            "mechanical_interfaces": "Bewegliche und rotierende Teile des Motors (Welle). Optional integriertes Getriebe.",
            "pneumatic_hydraulic_interfaces": "Keine pneumatischen oder hydraulischen Schnittstellen.",
            "software_interfaces": "",
            "operating_conditions": "Umgebungstemperatur -20 Grad C bis 40 Grad C.",
            "operating_modes": "Betrieb. Montage, Installation und Inbetriebnahme. Reinigung. Instandhaltung. Fehlersuche und -beseitigung. Demontage und Ausserbetriebnahme.",
            "person_groups": "Laie, unterwiesene Person, befaehigte Person, Fachpersonal.",
            "qualification_requirements": "Transport: Laie. Montage, Installation und Inbetriebnahme: Unterwiesene Person. Betrieb und Reinigung: Laie. Instandhaltung sowie Fehlersuche und -beseitigung: Fachpersonal. Demontage und Ausserbetriebnahme: Unterwiesene Person.",
            "emergency_stop": "",
            "malfunction_interventions": "Ausloesen des Thermoschalters bei Uebertemperatur.",
            "other_limits": "Es bestehen keine weiteren relevanten Grenzen.",
        },
    },
    {
        "machine_name": "Rundschweissanlage Schwingarm",
        "machine_type": "welding",
        "manufacturer": "Eigenbau GmbH",
        "limits_form": {
            "general_description": "Die Rundschweissanlage Schwingarm ist eine Rundnahtschweissanlage als Auf-Tisch-Version. Sie kann durch ein START/STOP-Fusspedal oder einen Fussregler bedient werden. Die Anlage ist mit einem pneumatisch bewegten Brennerarm ausgestattet. Der Reitstock kann zur Vermeidung von Torsionskraeften mit einem Synchronantrieb ausgestattet werden. Die Anlage ermoeglicht es, Formiergas durch die Hohlwelle an das Werkstueck zu fuehren. Die Maschine ist zum Anschluss an MIG/MAG- und TIG-Stromquellen sowie fuer Impulslichtbogen vorgesehen.",
            "intended_purpose": "Die Schwingarm Rundschweissanlage dient zum manuellen oder automatisierten Schweissen von Rundnaehten.",
            "foreseeable_misuses": "Bearbeitung von Werkstuecken mit mehr als 25 kg Gewicht. Schweissen im Viertaktmodus. Schweissen ohne Masseanschluss.",
            "spatial_limits": "Leitfaehige Oberflaechen des Gehaeuses (elektrischer Schlag). Brenner (Verbrennung). Brennerhalterung (Quetschgefahr). Bereich unterhalb der Schweissanlage (Verbrennung, Quetschgefahr).",
            "temporal_limits": "Wartungsintervalle gemaess Herstellerangaben (halbjaehrlich, jaehrlich, taeglich, woechentlich).",
            "technical_data": "Maximale mechanische Belastung 25 kg. Drehmoment Getriebe A/B/C 33/98/196 Nm. Geschwindigkeitsbereiche 0,01 bis 25 U/min. Kippbereich 0 bis 90 Grad, stufenlos manuell. Maximaler Abstand zwischen den Flanschen 500 bzw. 800 mm. Maximaler Werkstueckdurchmesser 340 mm. Maximaler Schweissstrom DC 350 / AC 270 A. Durchmesser Hohlwelle 28 mm.",
            "electrical_interfaces": "Anschluss an MIG/MAG- und TIG-Stromquellen sowie Impulslichtbogen. Maximaler Schweissstrom DC 350 / AC 270 A. Leitfaehige Oberflaechen des Gehaeuses. Masseanschluss erforderlich.",
            "mechanical_interfaces": "Werkstuecke werden von Hand mithilfe zweier Backenfutter eingespannt und pneumatisch gesichert. Reitstock, optional mit Synchronantrieb. Rotierende Werkstueckaufnahme. Brennerhalterung mit Quetschgefahr.",
            "pneumatic_hydraulic_interfaces": "Pneumatisch bewegter Brennerarm. Pneumatische Sicherung der Werkstuecke in den Backenfuttern.",
            "software_interfaces": "Integrierte Steuerung mit Bedienpanel. Bedienung ueber START/STOP-Fusspedal oder Fussregler.",
            "operating_conditions": "Verwendung in Innenraeumen; Hoehen bis 2000 m; Umgebungstemperatur 5 Grad C bis 40 Grad C.",
            "operating_modes": "Manuelles Schweissen. Automatisiertes Schweissen. Reinigung. Instandhaltung.",
            "person_groups": "Laien, unterwiesene Personen, Fachpersonal.",
            "qualification_requirements": "Transport: Laien. Aufstellung, Montage, Installation und Inbetriebnahme: Fachpersonal. Betrieb: Unterwiesene Person. Reinigung: Laien nach Einweisung. Instandhaltung und Fehlersuche: Unterwiesene Person (einfache Arbeiten) oder Fachpersonal (komplexere Arbeiten). Demontage und Ausserbetriebnahme: Fachpersonal.",
            "emergency_stop": "Bedienung ueber START/STOP-Fusspedal.",
            "malfunction_interventions": "",
            "other_limits": "Beim Schweissen entstehen Schweissrauch und es wird Formiergas (Schutzgas) eingesetzt. Es bestehen keine weiteren relevanten Grenzen.",
        },
    },
]


def main():
    for m in MACHINES:
        print("=" * 70)
        print(f"MASCHINE: {m['machine_name']}  [machine_type={m['machine_type']}]")
        status, resp = call("POST", "/projects", {
            "machine_name": m["machine_name"],
            "machine_type": m["machine_type"],
            "manufacturer": m["manufacturer"],
            "metadata": {"limits_form": m["limits_form"]},
        })
        if status not in (200, 201):
            print(f"  CREATE FEHLER {status}: {resp}")
            continue
        pid = resp.get("project", resp).get("id") if isinstance(resp, dict) else None
        print(f"  Projekt angelegt: {pid}")

        status, resp = call("POST", f"/projects/{pid}/initialize?force=true")
        if status != 200:
            print(f"  INIT FEHLER {status}: {resp}")
            continue
        summ = resp.get("summary", {})
        print(f"  Seed OK: Komponenten={summ.get('components')} Patterns={summ.get('patterns')} "
              f"Hazards={summ.get('hazards')} Massnahmen={summ.get('mitigations')} Normen={summ.get('norms')}")
        print(f"  PROJECT_ID={pid}")


if __name__ == "__main__":
    main()
