from collections import namedtuple
from typing import List
from ruamel.yaml import YAML

DeviceInfo = namedtuple("DeviceInfo", ['csv_name', 'display_name'])
yaml = YAML()


def first_lower(s):
    if len(s) == 0:
        return s
    else:
        return s[0].lower() + s[1:]


def import_ets5_csv_file(csv_file):
    result = dict()
    with open(csv_file, encoding='utf-8') as f:
        for line in f:
            splitted_line = line.split(",")
            name = splitted_line[0].replace('"', "")
            group_address = splitted_line[1].replace('"', "")
            if '-' not in group_address:
                result[name.strip()] = splitted_line[1].replace('"', "").strip()
    return result


def create_dimmable_lights(device_info : List[DeviceInfo],
                           csv_contents,
                           postfix_on_off_write=" Schalten",
                           postfix_on_off_read=" RM Schalten",
                           postfix_dim=" Dimmen",
                           postfix_brightness_write=" Helligkeit",
                           postfix_brightness_read=" RM Helligkeit"):

    result = []
    for entry in device_info:
        try:
            display_name = entry.display_name
            on_off_write_addr = csv_contents[entry.csv_name + postfix_on_off_write]
            on_off_read_addr = csv_contents[entry.csv_name + postfix_on_off_read]
            dimm_addr = csv_contents[entry.csv_name + postfix_dim]
            brightness_write_addr = csv_contents[entry.csv_name + postfix_brightness_write]
            brightness_read_addr = csv_contents[entry.csv_name + postfix_brightness_read]

            result.append({
                'platform': 'knx',
                'address': on_off_write_addr,
                'state_address': on_off_read_addr,
                'name': display_name,
                'brightness_address': brightness_write_addr,
                'brightness_state_address': brightness_read_addr,
            })
        except KeyError as e:
            raise ValueError("Skipping %s - Could not find CSV File entry:  %s" % (entry.csv_name, str(e)))

    return result


def write_yaml(device_dict):
    pass


if __name__ == '__main__':
    knx_dimmable_lights = [
        DeviceInfo('Wohnzimmerlampe', 'Wohnzimmer Deckenlampe'),
        DeviceInfo('EsszimmerlampeWest', 'Esszimmer Deckenlampe West'),
        DeviceInfo('EsszimmerlampeMitte', 'Esszimmer Deckenlampe Mitte'),
        DeviceInfo("EsszimmerWandlampe", 'Esszimmer Schrankleuchte'),
        DeviceInfo("Küchenlampe", "Küche Deckenlampe"),
        DeviceInfo("AussenleuchteUntenSO", "Aussen Terassenlicht"),
        DeviceInfo("Gang", "Gang Licht"),
        DeviceInfo("Bad", "Bad Licht"),
        DeviceInfo("GangWindfang", "Gang Einganglicht"),
        DeviceInfo("LichtWaschküche", "Waschküche Licht"),
    ]
    imported_csv = import_ets5_csv_file('export_project1.csv')
    imported_csv.update(import_ets5_csv_file('export_project2.csv'))

    devices = {
        'light': create_dimmable_lights(knx_dimmable_lights, imported_csv),
    }
    yaml.dump(devices, open('knx_devices.yaml', 'w'))


def createLights(csvContents, idToRoomMap, knxSendClient, knxRecvClient,
             postfixWrite=" Schalten", postfixRead=" RM Schalten"):
    from pysmarthome.backends.knx.devices import Light
    result = []

    for csvName, info in idToRoomMap.items():
        try:
            room = info['room']
            displayName = info['displayName']
            deviceId = info['id']
            onOffWriteAddr = csvContents[csvName + postfixWrite]
            onOffReadAddr = csvContents[csvName + postfixRead]
            l = Light(deviceId, displayName, room, onOffWriteAddr, onOffReadAddr, knxSendClient, knxRecvClient, )
            result.append(l)
        except KeyError as e:
            raise ValueError("Skipping %s - Could not find CSV File entry:  %s" % (csvName, str(e)))

    return result


def createBells(csvContents, idToRoomMap, knxSendClient, knxRecvClient,
                postfixWrite=" Schalten", postfixRead=" RM Schalten"):
    from pysmarthome.backends.knx.devices import Bell
    result = []

    for csvName, info in idToRoomMap.items():
        try:
            room = info['room']
            displayName = info['displayName']
            deviceId = info['id']
            onOffWriteAddr = csvContents[csvName + postfixWrite]
            if csvName + postfixRead in csvContents:
                onOffReadAddr = csvContents[csvName + postfixRead]
            else:
                onOffReadAddr = None

            l = Bell(deviceId, displayName, room, onOffWriteAddr, onOffReadAddr, knxSendClient, knxRecvClient, )
            result.append(l)
        except KeyError as e:
            raise ValueError("Skipping %s - Could not find CSV File entry:  %s" % (csvName, str(e)))

    return result


def createShutters(csvContents, idToRoomMap, knxSendClient, knxRecvClient,
                   postfixLongAddr=" Lang", postfixShortAddr=" Kurz", postfixReadPosition=" RM Position",
                   postfixSetPosition=" Position"):
    from pysmarthome.backends.knx.devices import Shutter
    result = []

    for csvName, contents in idToRoomMap.items():
        try:
            longAddr = csvContents[csvName + postfixLongAddr]
            shortAddr = csvContents[csvName + postfixShortAddr]
            readPosAddr = csvContents[csvName + postfixReadPosition]
            setPosAddr = csvContents[csvName + postfixSetPosition]
            if type(contents) is dict:
                displayName = contents['displayName']
                room = contents['room']
                deviceId = contents['id']
            else:
                displayName = csvName
                room = contents
                deviceId = first_lower(csvName)

            s = Shutter(deviceId, displayName, room, shortAddr, longAddr, setPosAddr, readPosAddr,
                        knxSendClient, knxRecvClient)
            result.append(s)

        except KeyError as e:
            raise ValueError("Skipping %s - Could not find CSV File entry:  %s" % (csvName, str(e)))

    return result
