(in-package :sgp2dot)


(defparameter *hosts* nil "Contains hosts found in the Simgrid XML platform file")
(defparameter *links* nil "Contains links found in the Simgrid XML platform file")


(defun handle-host (attributes)
  (push (cdr (assoc :|id| attributes)) *hosts*))

(defun handle-route (attributes)
  (push `(,(cdr (assoc :|src| attributes)) . ,(cdr (assoc :|dst| attributes))) *links* ))

(defun handle-element (name attributes seed)
  (declare (ignore seed)) ; Ignore "unused argument" warning
  (cond ((eq name :|host|) (handle-host attributes))
        ((eq name :|route|) (handle-route attributes))))


;;; Program entry point
(defun convert (platform dot-file)
  "Parse Simgrid platform then write it into a dot file."
  (let ((xml-parser (make-instance 'xml-parser-state
				                 :seed (cons 0 0)
                                 :new-element-hook #'handle-element)))
    ;; Parse Simgrid Platform
    (with-open-file (stream-file platform :direction :input)
      (start-parse-xml stream-file xml-parser))
    ;; Write parsed host and list to a dot file
    (with-open-file (stream dot-file :direction :output :if-exists :overwrite :if-does-not-exist :create)
      ;; Add header
      (format stream "graph Network {~%")
      (format stream "graph [outputorder=\"edgesfirst\"]")
      (format stream "node [shape=circle,style=filled]")
      ;; Add links
      (dolist (link *links*)
        (format stream "~t~a -- ~a ~%" (car link) (cdr link)))
      ;; Add hosts
      (dolist (host *hosts*)
        (format stream "~t~a~%" host))
      ;; Add footer
      (format stream "}~%"))))