import csv
import re
from typing import NamedTuple, IO, Iterable, Tuple, Optional

from lxml import etree  # type: ignore

XML_NS = "{http://knx.org/xml/ga-export/01}"


class GroupAddressDesc(NamedTuple):
    name: str
    gad: Tuple[int, int, int]
    description: Optional[str]
    central: Optional[bool]
    type: Optional[str]


RE_DTP = re.compile(r'DPST-(\d+)-(\d+)')


def read_xml(file: IO[bytes]) -> Iterable[GroupAddressDesc]:
    for _event, elem in etree.iterparse(file):
        if elem.tag == XML_NS + "GroupAddress":
            gad = tuple(int(v) for v in elem.attrib["Address"].split('/'))
            dpt_raw: str = elem.attrib.get('DPTs')
            dpt = None
            if dpt_raw is not None:
                dpt_match = RE_DTP.match(dpt_raw)
                if dpt_match:
                    dpt = "{}.{:03}".format(int(dpt_match[1]), int(dpt_match[2]))
            yield GroupAddressDesc(
                elem.attrib["Name"],
                gad,  # type: ignore
                elem.attrib.get("Description"),
                elem.attrib.get("Central") == 'true',
                dpt)
            elem.clear()


def read_csv(file: IO[str]) -> Iterable[GroupAddressDesc]:
    reader = csv.DictReader(file)
    # TODO
    return []


def pythonize_name(name: str) -> str:
    # TODO
    return name


def write_file(file: IO[str], group_addresses: Iterable[GroupAddressDesc]) -> None:
    file.write("""
# Generated by Smart Home Connect's generate_knx_group_variables.py.

import shc.knx

knx_connection = shc.knx.KNXConnector()

""")
    for group_address in group_addresses:
        file.write("{name} = knx_connection.group(shc.knx.KNXGAD({}, {}, {}), {}")
