import type { Node, Edge } from '@xyflow/react' import type { DeviceNodeData } from '@/components/network/nodes/DeviceNode' import type { GroupNodeData } from '@/types/network-diagram' // Maps our device slugs to draw.io Cisco stencil shape styles const SLUG_TO_DRAWIO_STYLE: Record = { 'router': 'shape=mxgraph.cisco.routers.router;', 'switch': 'shape=mxgraph.cisco.switches.layer_3_switch;', 'access-point': 'shape=mxgraph.cisco.misc.access_point;', 'load-balancer': 'shape=mxgraph.cisco.misc.generic_building;', 'firewall': 'shape=mxgraph.cisco.firewalls.firewall;', 'badge-reader': 'shape=mxgraph.cisco.misc.generic_building;', 'server': 'shape=mxgraph.cisco.servers.standard_server;', 'vm': 'shape=mxgraph.cisco.servers.standard_server;', 'container': 'shape=mxgraph.cisco.servers.standard_server;', 'nas': 'shape=mxgraph.cisco.storage.tape_storage_library;', 'san': 'shape=mxgraph.cisco.storage.tape_storage_library;', 'cloud-storage': 'shape=mxgraph.cisco.misc.cloud;', 'cloud': 'shape=mxgraph.cisco.misc.cloud;', 'aws': 'shape=mxgraph.cisco.misc.cloud;', 'azure': 'shape=mxgraph.cisco.misc.cloud;', 'gcp': 'shape=mxgraph.cisco.misc.cloud;', 'isp': 'shape=mxgraph.cisco.misc.cloud;', 'workstation': 'shape=mxgraph.cisco.computers_and_peripherals.pc;', 'laptop': 'shape=mxgraph.cisco.computers_and_peripherals.laptop;', 'tablet': 'shape=mxgraph.cisco.computers_and_peripherals.laptop;', 'phone': 'shape=mxgraph.cisco.computers_and_peripherals.ip_phone;', 'printer': 'shape=mxgraph.cisco.computers_and_peripherals.printer;', 'ups': 'shape=mxgraph.cisco.misc.generic_building;', 'pdu': 'shape=mxgraph.cisco.misc.generic_building;', 'rack': 'shape=mxgraph.cisco.misc.generic_building;', 'patch-panel': 'shape=mxgraph.cisco.misc.generic_building;', 'camera': 'shape=mxgraph.cisco.misc.generic_building;', 'nvr': 'shape=mxgraph.cisco.misc.generic_building;', 'iot': 'shape=mxgraph.cisco.misc.generic_building;', } const BASE_NODE_STYLE = 'sketch=0;html=1;pointerEvents=1;dashed=0;fillColor=#036897;strokeColor=#ffffff;strokeWidth=2;verticalLabelPosition=bottom;verticalAlign=top;align=center;outlineConnect=0;' const GROUP_STYLE = 'swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;collapsible=0;marginBottom=0;swimlaneHead=0;fillColor=none;' function esc(s: string): string { return s .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') } export function exportToDrawio(nodes: Node[], edges: Edge[]): string { const cells: string[] = [ '', '', ] for (const node of nodes) { const w = typeof node.style?.width === 'number' ? node.style.width : (node.measured?.width ?? 120) const h = typeof node.style?.height === 'number' ? node.style.height : (node.measured?.height ?? 120) const x = node.position.x const y = node.position.y const parentId = node.parentId ?? '1' if (node.type === 'group') { const gd = node.data as GroupNodeData cells.push( `` + `` + ``, ) } else { const dd = node.data as DeviceNodeData const slug = dd.deviceType ?? 'server' const shapeStyle = SLUG_TO_DRAWIO_STYLE[slug] ?? 'rounded=1;whiteSpace=wrap;html=1;' cells.push( `` + `` + ``, ) } } for (const edge of edges) { const label = typeof edge.label === 'string' ? edge.label : '' cells.push( `` + `` + ``, ) } const xml = `\n` + `\n` + cells.join('\n') + `\n` return xml }