from diagrams import Cluster, Diagram, Edge
from diagrams.azure.compute import Disks, VMLinux
from diagrams.azure.network import ApplicationGateway, DNSZones
from diagrams.generic.compute import Rack
from diagrams.generic.network import Firewall, VPN
from diagrams.onprem.client import Client, Users
from diagrams.onprem.container import Docker
from diagrams.onprem.database import PostgreSQL
from diagrams.onprem.inmemory import Redis
from diagrams.onprem.network import Caddy

graph_attr = {
    "bgcolor": "transparent",
    "pad": "0.25",
    "rankdir": "LR",
    "splines": "ortho",
    "nodesep": "0.52",
    "ranksep": "0.95",
    "fontname": "Inter",
    "fontsize": "24",
    "labelloc": "t",
}

node_attr = {
    "fontname": "Inter",
    "fontsize": "11",
    "margin": "0.05,0.03",
    "imagescale": "true",
}

edge_attr = {
    "fontname": "Inter",
    "fontsize": "9",
    "color": "#4A5568",
    "fontcolor": "#4A5568",
    "arrowsize": "0.72",
    "penwidth": "1.8",
}

access_attr = {
    "fillcolor": "#F5F5F5",
    "color": "#666666",
    "fontcolor": "#333333",
    "fontsize": "13",
    "penwidth": "1.4",
    "style": "rounded,filled",
    "labeljust": "l",
    "labelloc": "t",
}

azure_attr = {
    "fillcolor": "#EAF1FB",
    "color": "#0078D4",
    "fontcolor": "#0F5BA8",
    "fontsize": "14",
    "penwidth": "1.7",
    "style": "rounded,filled",
    "labeljust": "l",
    "labelloc": "t",
}

vm_attr = {
    "fillcolor": "#FFFFFF",
    "color": "#5B9BD5",
    "fontcolor": "#24425F",
    "fontsize": "13",
    "penwidth": "1.5",
    "style": "rounded,filled",
    "labeljust": "l",
    "labelloc": "t",
}

compose_attr = {
    "fillcolor": "#F3F7FB",
    "color": "#7B8FA8",
    "fontcolor": "#31445A",
    "fontsize": "13",
    "penwidth": "1.4",
    "style": "rounded,filled,dashed",
    "labeljust": "l",
    "labelloc": "t",
}

with Diagram(
    "InvenTree on Azure · Python diagrams",
    filename="/opt/diagram-tools-lab/site/assets/inventree-azure-python",
    direction="LR",
    curvestyle="ortho",
    outformat=["png", "svg"],
    show=False,
    graph_attr=graph_attr,
    node_attr=node_attr,
    edge_attr=edge_attr,
):
    users = Users("Benutzer\nWebbrowser")
    mobile = Client("Managed\nMobile App")

    with Cluster("Kontrollierter Zugriffspfad", graph_attr=access_attr):
        fqdn = DNSZones("inventree.example.com\nFQDN")
        access = ApplicationGateway("VPN / ZTNA / WAF\nForti Access Proxy")

    with Cluster("Azure · Schweiz oder EU/EWR", graph_attr=azure_attr):
        vm = VMLinux("Linux Azure VM\nUbuntu LTS / Debian\n2 vCPU · 4 GB RAM\n128 GB Storage")

        with Cluster("VM Boundary", graph_attr=vm_attr):
            with Cluster("Docker Compose Betrieb", graph_attr=compose_attr):
                proxy = Caddy("Caddy\nReverse Proxy")
                app = Docker("InvenTree\nWeb / API")
                worker = Docker("InvenTree\nWorker")
                db = PostgreSQL("PostgreSQL\nproduktiv")
                cache = Redis("Redis")

            volume = Disks("Persistent Volume\nMedia · Static\nConfig · Secrets\nBackups")

    mgmt = Rack("Datacenter\nManagement")
    notes = Firewall("Security Notes\nNur TCP 443 extern\nKeine Containerports\nKein public SSH\nDaten CH oder EU/EWR")

    https = {"color": "#1F7A52", "fontcolor": "#1F7A52", "penwidth": "2.4"}
    internal = {"color": "#4A5568", "fontcolor": "#4A5568", "penwidth": "1.8"}
    mgmt_edge = {"color": "#7B8FA8", "fontcolor": "#607089", "style": "dashed", "penwidth": "1.7", "constraint": "false"}
    volume_edge = {"color": "#8C4FFF", "fontcolor": "#6B46C1", "style": "dashed", "penwidth": "1.8", "constraint": "false"}

    users >> Edge(label="HTTPS TCP 443", **https) >> fqdn
    mobile >> Edge(label="HTTPS TCP 443", **https) >> fqdn
    fqdn >> Edge(label="kontrollierter Pfad", **https) >> access
    access >> Edge(label="443 only", **https) >> proxy

    proxy >> Edge(label="reverse proxy", **internal) >> app
    app >> Edge(label="SQL", **internal) >> db
    app >> Edge(label="cache / queue", **internal) >> cache
    worker >> Edge(label="jobs SQL", **internal) >> db
    worker >> Edge(label="queue", **internal) >> cache
    app >> Edge(label="media static config", **volume_edge) >> volume
    worker >> Edge(label="backups jobs", **volume_edge) >> volume

    mgmt >> Edge(label="separater Managementzugriff\nkein oeffentlicher SSH", **mgmt_edge) >> vm
    notes >> Edge(label="policy", **mgmt_edge) >> access
