# This is just an example to get you started. A typical binary package
# uses this file as the main entry point of the application.

import zippy/ziparchives
import streams
import xmlparser
import xmltree
import tables
import strtabs
import strutils

type
  DataType = enum
    STRING_TYPE,
    UNSIGNED_BYTE_TYPE,
    UNSIGNED_SHORT_TYPE,
    FLOAT_TYPE,
    HEX_BINARY_TYPE,
    BACOID_TYPE,
    ENUM_TYPE,
    LIST_TYPE,
    ARRAY_TYPE,
    STRUCT_TYPE
  BACoid = object
    objectID {.bitsize:10.}: uint32
    instanceID {.bitsize:22.}: uint32
  Enum = object
    `set`: int
    value: int
  Data = object
    case kind: DataType
    of STRING_TYPE:
      `string`: string
    of UNSIGNED_BYTE_TYPE:
      unsignedByte: uint8
    of UNSIGNED_SHORT_TYPE:
      unsignedShort: uint16
    of FLOAT_TYPE:
      `float`: float
    of HEX_BINARY_TYPE:
      `high`, `low`: int64
    of BACOID_TYPE:
      bacoid: BACoid
    of ENUM_TYPE:
      `enum`: Enum
    of LIST_TYPE, ARRAY_TYPE, STRUCT_TYPE:
      discard
  BACnetObject = object
    bacnetType: int
    bacnetID: int
    metasysRef: string
    properties: seq[BACnetProperty]
  BACnetProperty = object
    bacnetID: int
    data: Data

proc parseBACoid(xml: XmlNode): BACoid =
  for key, val in xml.attrs.pairs:
    echo key, ": ", val
    if key == "id":
      result.objectID = val.parseInt.uint32
  for item in xml.items:
    echo item.kind
    if item.kind == xnText:
      echo item.text
      result.instanceID = item.text.parseInt.uint32

proc parseData(xml: XmlNode): Data =
  for item in xml.items:
    if item.tag == "BACoid":
      var data = Data(kind: BACOID_TYPE)
      data.bacoid = item.parseBACoid
      echo data
      var data2 = data
      echo data2
      return data

proc parseProperty(xml: XmlNode): BACnetProperty =
  for key, val in xml.attrs.pairs:
    if key == "id":
      result.bacnetID = val.parseInt
  for item in xml.items:
    if item.tag == "data":
      result.data = item.parseData
      echo result.data

proc parseObject(xml: XmlNode): BACnetObject =
  for key, val in xml.attrs.pairs:
    if key == "ref":
      result.metasysRef = val
    elif key == "objectid":
      result.bacnetID = val.parseInt
  for item in xml.items:
    if item.tag == "property":
      result.properties.add(item.parseProperty())
      if result.properties[^1].data.kind == BACOID_TYPE:
        result.bacnetType = result.properties[^1].data.bacoid.objectID.int

when isMainModule:
  let zip = openZipArchive("Test NCE.caf")
  let caf = zip.extractFile("Test NCE.caf.xml")
  #echo caf

  var objects: Table[string, BACnetObject]
  var errors: seq[string]

  var xml = parseXml(newStringStream(caf), "Test NCE.caf", errors)
  #echo xml

  if xml.kind == xnElement:
    for item in xml.items:
      echo item.tag
      if item.tag == "object":
        var currObject = item.parseObject()
        echo currObject
        objects[currObject.metasysRef] = currObject


  zip.close()