;; ============================================================
;; tests.lsp - Test- und Hilfsfunktionen
;; ============================================================

(defun c:CALLPYTHON ( / log-pfad py-skript return-datei cmd fh zeile)
  (setq log-pfad (getenv "DXFM_LOG"))
  (setq py-skript (strcat (getenv "DXFM_LIB") "\\testpycall.py"))
  (setq return-datei (strcat log-pfad "\\testpycall_return.txt"))
  (if (findfile py-skript)
    (progn
      (setq cmd (strcat "python \"" py-skript "\" \"" log-pfad "\""))
      (command "_.SHELL" cmd)
      (if (findfile return-datei)
        (progn
          (setq fh (open return-datei "r"))
          (setq zeile (read-line fh))
          (close fh)
          (princ (strcat "\n[SSG_LIB] Python Rueckgabe: " zeile))
        )
        (princ "\n[SSG_LIB] WARNUNG: Keine Rueckgabe von Python erhalten.")
      )
    )
    (princ (strcat "\n[SSG_LIB] FEHLER: " py-skript " nicht gefunden!"))
  )
  (princ)
)

;; ============================================================
;; EXPORTCSV - Alle INSERT-Entities sammeln und als JSON exportieren
;; Anschliessend Python-Skript aufrufen fuer CSV-Erzeugung
;; ============================================================

;; --- Wert sicher als String zurueckgeben ---
(defun csv:to-str (val)
  (cond
    ((null val) "")
    ((= (type val) 'STR) val)
    ((= (type val) 'INT) (itoa val))
    ((= (type val) 'REAL) (rtos val 2 6))
    (T (vl-princ-to-string val))
  )
)

;; --- String fuer JSON escapen (Anfuehrungszeichen) ---
(defun csv:json-escape (s / pos result ch)
  (setq result "")
  (setq pos 1)
  (repeat (strlen s)
    (setq ch (substr s pos 1))
    (cond
      ((= ch "\"") (setq result (strcat result "\\\"")))
      ((= ch "\\") (setq result (strcat result "\\\\")))
      (T (setq result (strcat result ch)))
    )
    (setq pos (1+ pos))
  )
  result
)

;; --- Attribute eines INSERT-Blocks als JSON-Objekt lesen ---
;; ename = Entity-Name des INSERT
;; Rueckgabe: String wie {"TAG1":"Wert1","TAG2":"Wert2"}
(defun csv:read-attribs (ename / obj typ tag wert result first-item)
  (setq obj (entnext ename))
  (setq result "{")
  (setq first-item T)
  (while (and obj (not (equal (cdr (assoc 0 (entget obj))) "SEQEND")))
    (setq typ (cdr (assoc 0 (entget obj))))
    (if (equal typ "ATTRIB")
      (progn
        (setq tag  (cdr (assoc 2 (entget obj))))
        (setq wert (cdr (assoc 1 (entget obj))))
        (if (not first-item)
          (setq result (strcat result ","))
        )
        (setq result (strcat result
          "\"" (csv:json-escape tag) "\":\""
          (csv:json-escape wert) "\""))
        (setq first-item nil)
      )
    )
    (setq obj (entnext obj))
  )
  (strcat result "}")
)

;; --- Einen INSERT-Block als JSON-Objekt schreiben ---
(defun csv:block-to-json (ename / ed blk-name layer pt rotation handle attribs has-attribs)
  (setq ed (entget ename))
  (setq blk-name  (cdr (assoc 2 ed)))
  (setq layer     (cdr (assoc 8 ed)))
  (setq pt        (cdr (assoc 10 ed)))
  (setq rotation  (cdr (assoc 50 ed)))
  (setq handle    (cdr (assoc 5 ed)))
  (setq has-attribs (cdr (assoc 66 ed)))
  (if (null rotation) (setq rotation 0.0))
  (if has-attribs
    (setq attribs (csv:read-attribs ename))
    (setq attribs "{}")
  )
  (strcat
    "  {\"block_name\":\"" (csv:json-escape blk-name) "\""
    ",\"layer\":\"" (csv:json-escape layer) "\""
    ",\"handle\":\"" (csv:json-escape handle) "\""
    ",\"x\":" (rtos (car pt) 2 4)
    ",\"y\":" (rtos (cadr pt) 2 4)
    ",\"z\":" (rtos (caddr pt) 2 4)
    ",\"rotation\":" (rtos (* (/ rotation pi) 180.0) 2 4)
    ",\"attribs\":" attribs
    "}"
  )
)

;; --- Hauptfunktion: EXPORTCSV ---
(defun c:EXPORTCSV ( / ss i ename json-str out-pfad py-skript cmd fh
                       ergebnis-pfad first-block count)
  (princ "\n[EXPORTCSV] Sammle alle Bloecke der Zeichnung...")

  ;; Alle INSERT-Entities in der Zeichnung
  (setq ss (ssget "X" (list (cons 0 "INSERT"))))
  (if (null ss)
    (progn
      (princ "\n[EXPORTCSV] Keine Bloecke in der Zeichnung gefunden.")
      (princ)
    )
    (progn
      (setq count (sslength ss))
      (princ (strcat "\n[EXPORTCSV] " (itoa count) " Bloecke gefunden."))

      ;; JSON-Datei zusammenbauen
      (setq out-pfad (strcat (getenv "DXFM_RESULTS") "/export_raw.json"))
      (setq fh (open out-pfad "w"))
      (if (null fh)
        (progn
          (princ (strcat "\n[EXPORTCSV] FEHLER: Kann Datei nicht oeffnen: " out-pfad))
          (princ)
        )
        (progn
          (write-line "[" fh)
          (setq i 0)
          (setq first-block T)
          (while (setq ename (ssname ss i))
            (if (not first-block)
              (write-line "," fh)
            )
            (setq json-str (csv:block-to-json ename))
            (write-line json-str fh)
            (setq first-block nil)
            (setq i (1+ i))
          )
          (write-line "]" fh)
          (close fh)
          (princ (strcat "\n[EXPORTCSV] JSON geschrieben: " out-pfad))

          ;; Python-Skript aufrufen
          (setq py-skript (strcat (getenv "DXFM_LIB") "/export_csv.py"))
          (if (findfile py-skript)
            (progn
              (setq ergebnis-pfad (strcat (getenv "DXFM_RESULTS") "/export.csv"))
              (setq cmd (strcat "python \"" py-skript "\""
                                " \"" out-pfad "\""
                                " \"" (getenv "DXFM_DATA") "\""
                                " \"" ergebnis-pfad "\""))
              (princ (strcat "\n[EXPORTCSV] Rufe Python auf..."))
              (command "_.SHELL" cmd)
              (if (findfile ergebnis-pfad)
                (princ (strcat "\n[EXPORTCSV] CSV erstellt: " ergebnis-pfad))
                (princ "\n[EXPORTCSV] WARNUNG: CSV-Datei wurde nicht erzeugt.")
              )
            )
            (princ (strcat "\n[EXPORTCSV] FEHLER: Python-Skript nicht gefunden: " py-skript))
          )
        )
      )
    )
  )
  (princ)
)
