# ruff: noqa
# mypy: ignore-errors
"""Automotive convergence stress test — does the SAME capability survive MANY sources? (Phase Ω, test #2)

Environmental proved domain-agnosticism. This tests a different property: can ONE capability be fed by
many overlapping Requirement Sources at once without the model becoming unstable? Realistic setup — a
supplier with ISO 9001 + IATF 16949 + TISAX + ASPICE + CSMS + SUMS developing an ECU for OEM X. Seven
sources (CRA, UNECE R155/CSMS, R156/SUMS, IATF, TISAX, ASPICE, OEM X) demand heavily OVERLAPPING caps.

Three new measurements the user asked for:
  - Capability Convergence : per capability, how many sources / how many distinct source TYPES feed it.
  - Existing-vs-New        : how many required caps reuse the EXISTING registry vs are genuinely new
                             (a registry-convergence signal — high reuse => the core is forming).
  - Business Leverage      : the most convergent cap satisfies N regulations AND unlocks a market — more
                             convincing to a GF than "satisfies five laws".

Data only (a YAML + injected Required caps), zero runtime code. Synthetic, no real names. No deploy.
Run:  cd backend-compliance && PYTHONPATH=. python3 reference_scenarios/automotive_convergence_stress_test.py
"""
from __future__ import annotations

import os
import yaml

from compliance.company import (
    CompanyContext, Certification, CapabilityMappingEntry, build_company_profile,
)
from compliance.reasoning.enums import Confidence
from compliance.transition_reasoning import (
    TransitionContext, TransitionGoal, TargetRequirement, assess_transition, CoverageStatus,
)

OUT = []


def w(s=""):
    OUT.append(s)


_HERE = os.path.dirname(__file__)
A = yaml.safe_load(open(os.path.join(_HERE, "..", "knowledge", "domains", "automotive", "source_capabilities.yaml"), encoding="utf-8"))
SOURCES = A["sources"]

# ── known capability universe = caps already modelled in the cyber + environmental patterns ──
_K = os.path.join(_HERE, "..", "knowledge", "transition_patterns")
known = set()
for f in os.listdir(_K):
    if f.endswith(".yaml"):
        p = yaml.safe_load(open(os.path.join(_K, f), encoding="utf-8"))
        known |= {a["capability"] for a in p.get("likely_covered", [])}
        known |= {d["capability"] for d in p.get("delta_requirements", [])}

# ── one multi-certified company profile (many overlapping sources) ──────────────────────────
prof_caps = A["company_profile_capabilities"]
cmap = {k: CapabilityMappingEntry(capability_ids=v, confidence=Confidence.MEDIUM) for k, v in prof_caps.items()}
profile = build_company_profile(
    CompanyContext(company_id="auto", certifications=[Certification(certification_id=k) for k in prof_caps]), cmap)

# ── required = union of all source caps for "ECU for OEM X"; delta via the SAME engine ───────
required = sorted({c for s in SOURCES for c in s["requires"]})
assess = assess_transition(TransitionContext(company_id="auto", target=TransitionGoal(target_id="ECU_for_OEM_X")),
                           [TargetRequirement(capability_id=c) for c in required], profile)
delta = sorted({c.capability_id for c in assess.coverage if c.status == CoverageStatus.MISSING})

# ── Capability Convergence: per cap -> sources + distinct source types ───────────────────────
conv = {}
for cap in required:
    srcs = [s for s in SOURCES if cap in s["requires"]]
    conv[cap] = (sorted(s["id"] for s in srcs), sorted({s["type"] for s in srcs}))
ranked = sorted(required, key=lambda c: (-len(conv[c][0]), -len(conv[c][1]), c))

# ── Existing-vs-New (registry convergence signal) ───────────────────────────────────────────
reuse = sorted(c for c in required if c in known)
fresh = sorted(c for c in required if c not in known)
reuse_pct = round(100 * len(reuse) / len(required)) if required else 0

w("# Automotive Convergence Stress Test — überlebt EINE Capability viele Quellen? (Phase Ω #2)")
w("")
w('_Nicht noch eine Domäne, sondern eine andere Eigenschaft: bleibt das Modell stabil, wenn dieselbe Capability gleichzeitig aus vielen überlappenden Quellen gespeist wird? Realistisch: ein Zulieferer (ISO 9001 + IATF 16949 + TISAX + ASPICE + CSMS + SUMS) entwickelt ein Steuergerät für OEM X. Sieben Quellen, bewusste Überlappung. Data-only, keine echten Namen._')
w("")
w("## 1. Sieben überlappende Quellen, eine Engine")
w("- Quellen: %s." % ", ".join("`%s`(%s)" % (s["id"], s["type"]) for s in SOURCES))
w('- **%d distinct geforderte Capabilities** für „Steuergerät → OEM X" — über dieselbe `assess_transition`-Engine, 0 neue Runtime-Klassen.' % len(required))
w("- Delta (fehlt dem Profil): **%d** Capabilities." % len(delta))
w("")

# ── 2. Capability Convergence ──────────────────────────────────────────────
w("## 2. Capability Convergence — dieselbe Capability aus vielen Quellen")
w("| Capability | Sources | Distinct Source Types | aus |")
w("|---|---:|---:|---|")
for cap in ranked[:8]:
    srcs, types = conv[cap]
    w("| `%s` | %d | %d | %s |" % (cap, len(srcs), len(types), ", ".join(srcs)))
w("")
top = ranked[0]
w('→ **`%s`** ist am konvergentesten: **%d Quellen** über **%d Quelltypen** — eine Maßnahme, viele Nachweiswelten. Genau hier entsteht der wirtschaftliche Nutzen (nicht „300 Gesetze", sondern „eine Capability ersetzt fünf Nachweiswelten").' % (top, len(conv[top][0]), len(conv[top][1])))
w("")

# ── 3. Existing-vs-New (registry convergence) ──────────────────────────────
w("## 3. Existing-vs-New — beginnt die Registry zu konvergieren?")
w("- **Bereits vorhandene MCAPs (Reuse aus Cyber/Umwelt): %d/%d = %d%%** — z. B. %s." % (
    len(reuse), len(required), reuse_pct, ", ".join("`%s`" % c for c in reuse[:5]) + " …"))
w("- **Genuin neu (Automotive-spezifisch): %d** — z. B. %s." % (
    len(fresh), ", ".join("`%s`" % c for c in fresh[:5]) + " …"))
w("- **Lesart:** %s" % (
    "Hohe Wiederverwendung → die Registry konvergiert, ein Kern bildet sich." if reuse_pct >= 60 else
    "Spürbare Wiederverwendung (%d%%) — der Kern beginnt sich zu bilden; der automotive-spezifische Rest (CSMS/SUMS/ASPICE/Funktionssicherheit) ist erwartbar neu. Kein Architekturbruch, sondern ein Hinweis auf den Reifegrad der Capability-Zerlegung." % reuse_pct))
w("")

# ── 4. Business Leverage ───────────────────────────────────────────────────
top_srcs, top_types = conv[top]
regs = [s for s in top_srcs if next(x["type"] for x in SOURCES if x["id"] == s) == "regulation"]
contracts = [s for s in top_srcs if next(x["type"] for x in SOURCES if x["id"] == s) == "contract"]
w('## 4. Business Leverage — Märkte + Regulierung, nicht nur „Gesetze"')
w("- `%s` erfüllt gleichzeitig **%d Regelwerke** (%s) **und** öffnet den **OEM-Markt** (%s)." % (
    top, len(regs), ", ".join(regs), ", ".join(contracts) or "—"))
w('- Managementsatz: **„Diese eine Capability erfüllt %d regulatorische Anforderungen UND ist Eintrittskarte zum OEM-Geschäft"** — überzeugender als „erfüllt %d Gesetze". (Regulatory Leverage zählt Regelwerke; **Business Leverage** zählt Regelwerke + erschlossene Märkte/Kunden.)' % (len(regs), len(regs)))
w("")

# ── Befund ─────────────────────────────────────────────────────────────────
w("## Befund")
w("")
w('> **Eine Capability aus bis zu %d Quellen über %d Quelltypen — das Modell blieb stabil (0 neue Runtime-Klassen, 0 neue Pipeline; reine Daten).** Convergence ist messbar geworden, und %d%% der Automotive-Anforderungen bilden auf BESTEHENDE MCAPs ab — die Registry beginnt zu konvergieren. Nächster Schritt ist bewusst KEINE neue Domäne, sondern **innehalten und die Registry analysieren**: welche MCAPs tauchen domänenübergreifend (CRA·MaschinenVO·OEM·TISAX·ASPICE·Umwelt) am häufigsten auf? Diese hochkonvergenten Capabilities sind der dauerhaft wertvollste Plattformkern.' % (
    len(conv[top][0]), len(conv[top][1]), reuse_pct))
w("")

print("\n".join(OUT))
