import json
import copy
import traceback

from iot_devices.host import get_class, discover
from iot_devices.device import Device

print("# Known Device Plugins\n")
print("All devices shown, some config params may be unlisted.")
print("This documentation is autogenerated with iot_devices_scan.py\n")
d = discover()
for i in sorted(d.keys()):
    print("## " + i+"\n")
    print(d[i].get('description', '')+'\n')
    try:
        c1 = get_class({'type': i})

        dpi = {}
        dpd = {}
        dpw = {}

        props = {}

        class c(c1):
            def string_data_point(self,
                                  name: str,
                                  description: str = "",
                                  unit: str = '',
                                  handler=None,
                                  interval: float = 0,
                                  writable=True,
                                  subtype: str = '',
                                  **kwargs):
                Device.string_data_point(self, name, description=description, unit=unit,
                                         handler=handler, interval=interval, writable=writable,
                                         subtype=subtype, **kwargs)
                dpi[name] = f"{subtype} {unit}"
                dpd[name] = description
                dpw[name] = writable

            def numeric_data_point(self,
                                   name: str,
                                   description: str = "",
                                   unit: str = '',
                                   handler=None,
                                   interval: float = 0,
                                   writable=True,
                                   subtype: str = '',
                                   **kwargs):
                Device.numeric_data_point(self, name, description=description, unit=unit,
                                          handler=handler, interval=interval, writable=writable,
                                          subtype=subtype, **kwargs)
                dpi[name] = f"""{subtype} {unit}""".strip()
                dpd[name] = description
                dpw[name] = writable

        defaults = {}
        tags = {}

        try:
            inst = c('DeviceName', {'type': i})
            props.update(inst.config_properties)

            for j in inst.config:
                if not j in props:
                    props[j] = {}

            tags.update(inst.datapoints)

        except Exception:
            print(traceback.format_exc())

        print("```python")
        print("from iot_devices.host import create_device")
        print("from " + d[i]['importable'] + " import " + i + "\n")

        print("dev = " + 'create_device(' + i + ', "name", {')
        count = 0
        for j in props:
            count += 1
            if j.startswith("device."):
                desc = props[j].get('description', '')
                if desc:
                    print(
                        '    # '+props[j].get('description', '')+"")
                ending = "," if count < len(props) else '\n})'
                if j in inst.config:
                    print(f"    '{j}': '{inst.config[j]}'"+ending)

        print("\n\n")
        for j in dpi:
            desc = dpd.get(j, '')
            if dpi[j].strip():
                print(f'# {dpi[j]}')
            if desc:
                print(f"# {desc}")
            print(f"print(dev.datapoints['{j}'])")
            print(f"# >>> {str(inst.datapoints[j])[:64]}\n")

            if dpw.get(j, False):
                print(f"# {j} is writable")
                print(
                    f"# dev.set_data_point('{j}', <your value> )\n")
        print("```")

    except Exception:
        print("## Error getting data for " + i)
        print(traceback.format_exc())

    print("")
