"""Support for lights from FHEM"""

import voluptuous as vol
import logging

from homeassistant.components.light import ATTR_BRIGHTNESS, PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS, Light
from homeassistant.const import CONF_NAME
import homeassistant.helpers.config_validation as cv

from . import DATA_FHEM

_LOGGER = logging.getLogger(__name__)


CONF_FHEM_IDS = 'fhem_ids'
CONF_DIMMER = 'dimmer'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_FHEM_IDS): vol.All(cv.ensure_list, [cv.string]),
    vol.Optional(CONF_DIMMER, default=False): cv.boolean,
    vol.Required(CONF_NAME): cv.string,
})


async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
    """Set up lights for KNX platform."""
    connection = hass.data[DATA_FHEM]
    #_LOGGER.error("FHEM platform config\n" + str(config))

    light = FhemLight(connection, config[CONF_NAME], config[CONF_FHEM_IDS], dimmer=config[CONF_DIMMER])
    for dev_id in config[CONF_FHEM_IDS]:
        connection.devices[dev_id] = light
    async_add_entities([light])


class FhemLight(Light):

    def __init__(self, connection, name, ids, dimmer=False):
        self._brightness = None
        self.connection = connection
        self._dimmer = dimmer
        self._ids = ids
        self._name = name
        self._available = True

    @property
    def should_poll(self):
        """No polling needed."""
        return False

    @property
    def brightness(self):
        return self._brightness

    @property
    def is_on(self):
        """Return true if light is on."""
        if self._brightness is not None:
            return self._brightness > 0
        else:
            return None

    @property
    def name(self):
        """Return the name of the KNX device."""
        return self._name

    @property
    def available(self) -> bool:
        return self._available and self.connection.connected

    @property
    def supported_features(self):
        """Flag supported features."""
        flags = 0
        if self._dimmer:
            flags |= SUPPORT_BRIGHTNESS
        return flags

    async def async_turn_on(self, **kwargs):
        brightness = kwargs.get(ATTR_BRIGHTNESS, self.brightness)
        if brightness is None:
            brightness = 255

        if self._dimmer:
            self.connection.fhem_set(self._ids[0], brightness / 255 * 100)
        else:
            self.connection.fhem_set(self._ids[0], 'on')

    async def async_turn_off(self, **kwargs):
        self.connection.fhem_set(self._ids[0], 'off')

    async def line_received(self, line):
        _LOGGER.info("FHEM line received (device): " + self.name + ": " + line)
        if line.startswith('dim:'):
            self._available = True
            _, new_dim_state, new_level = line.split(':')
            new_level = new_level.strip().lower()
            new_dim_state = new_dim_state.strip().lower()
            assert new_dim_state == 'stop' or new_dim_state == 'up' or new_dim_state == 'down'
            if new_dim_state == 'stop':
                if new_level == 'on':
                    self._brightness = 255
                elif new_level == 'off':
                    self._brightness = 0
                else:
                    new_level = int(float(new_level))  # first convert from string to floating point then truncate
                    assert 0 <= new_level <= 100
                    self._brightness = int(new_level / 100 * 255)
                await self.async_update_ha_state()
        elif line.startswith('level:') and not self._dimmer:
            self._available = True
            _, new_level = line.split(':')
            new_level = new_level.strip().lower()
            if new_level == 'on':
                self._brightness = 255
            elif new_level == 'off':
                self._brightness = 0
            else:
                try:
                    new_level = int(float(new_level))  # first convert from string to floating point then truncate
                    assert 0 <= new_level <= 100
                    self._brightness = int(new_level / 100 * 255)
                except ValueError:
                    pass
            await self.async_update_ha_state()
        elif line.startswith('overheat'):
            overheat = line.split(':')[1]
            overheat = overheat.strip().lower()
            assert overheat == 'on' or overheat == 'off'
            if overheat == 'on':
                self.hass.components.persistent_notification.async_create(
                    "FHEM: Light overheated: <br>"
                    "<b>{0}</b>".format(self.entity_id),
                    title="Light overheat")
        elif line.startswith('overload'):
            overload = line.split(':')[1]
            overload = overload.strip().lower()
            assert overload == 'on' or overload == 'off'
            if overload == 'on':
                self.hass.components.persistent_notification.async_create(
                    "FHEM: Light overloaded: <br>"
                    "<b>{0}</b>".format(self.entity_id),
                    title="Light overloaded")
        elif line.startswith('ResndFail') or line.startswith('MISSING ACK'):
            self._available = False
            await self.async_update_ha_state()
