from diagrams import Cluster, Diagram, Edge
from diagrams.k8s.compute import Deployment, StatefulSet, Pod, DaemonSet, Job
from diagrams.k8s.storage import PVC, StorageClass
from diagrams.generic.storage import Storage

graph_attr = {
    "fontsize": "13",
    "pad": "0.8",
    "nodesep": "0.6",
    "ranksep": "1.2",
}

with Diagram(
    "ExpertFab – Longhorn Storage Architektur",
    filename="storage_architecture",
    outformat="png",
    show=False,
    direction="TB",
    graph_attr=graph_attr,
):

    # ── Longhorn System Pods pro Node ─────────────────────────────────────────
    with Cluster("K3s Worker Nodes  (Longhorn System Pods)"):

        with Cluster("efsckubnode1  (4 vCPU / 8 GB)"):
            n1_mgr      = Pod("longhorn-manager")
            n1_csi      = Pod("longhorn-csi-plugin")
            n1_eng      = Pod("engine-image")
            n1_inst     = Pod("instance-manager")
            n1_driver   = Deployment("driver-deployer")
            n1_ui       = Deployment("longhorn-ui  (2×)")
            n1_attacher = Deployment("csi-attacher  (3×)")
            n1_prov     = Deployment("csi-provisioner  (3×)")
            n1_resizer  = Deployment("csi-resizer  (3×)")
            n1_snap     = Deployment("csi-snapshotter  (3×)")

        with Cluster("efsckubnode2  (4 vCPU / 8 GB)"):
            n2_mgr      = Pod("longhorn-manager")
            n2_csi      = Pod("longhorn-csi-plugin")
            n2_eng      = Pod("engine-image")
            n2_inst     = Pod("instance-manager")
            n2_smgr1    = Pod("share-manager\n(erpnext  RWX)")
            n2_smgr2    = Pod("share-manager\n(erpnext-logs  RWX)")
            n2_backup   = Job("daily-backup\n(CronJob)")

    # ── StorageClasses ────────────────────────────────────────────────────────
    with Cluster("StorageClasses  (driver.longhorn.io)"):
        sc_erpnext   = StorageClass("longhorn-erpnext\nRetain / Immediate")
        sc_paperless = StorageClass("longhorn-paperless\nRetain / Immediate")
        sc_default   = StorageClass("longhorn\nDelete / Immediate")

    # ── PVCs pro Namespace ────────────────────────────────────────────────────
    with Cluster("PVCs"):

        with Cluster("namespace: erpnext"):
            pvc_mariadb    = PVC("data-erpnext-mariadb-sts-0\n3 Gi  RWO")
            pvc_sites      = PVC("erpnext\n3 Gi  RWX")
            pvc_logs       = PVC("erpnext-logs\n1 Gi  RWX")

        with Cluster("namespace: paperless"):
            pvc_pl_media   = PVC("paperless-media\n10 Gi  RWO")
            pvc_pl_consume = PVC("paperless-consume\n5 Gi  RWO")
            pvc_pl_data    = PVC("paperless-data\n5 Gi  RWO")
            pvc_pl_pg      = PVC("postgres-data\n5 Gi  RWO")

        with Cluster("namespace: rabbitmq"):
            pvc_rmq        = PVC("rabbitmq-data-rabbitmq-0\n5 Gi  RWO")

        with Cluster("namespace: zitadel"):
            pvc_zit_pg     = PVC("postgres-data-postgres-0\n10 Gi  RWO")

    # ── StorageClass → PVC ────────────────────────────────────────────────────
    sc_erpnext   >> [pvc_mariadb, pvc_sites, pvc_logs]
    sc_paperless >> [pvc_pl_media, pvc_pl_consume, pvc_pl_data, pvc_pl_pg]
    sc_default   >> [pvc_rmq, pvc_zit_pg]

    # ── Share-Manager bedient die RWX-Volumes ─────────────────────────────────
    n2_smgr1 >> Edge(label="serves", style="dashed") >> pvc_sites
    n2_smgr2 >> Edge(label="serves", style="dashed") >> pvc_logs

    # ── Longhorn Manager koordiniert über beide Nodes ─────────────────────────
    n1_mgr >> Edge(style="dotted", color="gray") >> n2_mgr
