"""Support for MyQ-Enabled Garage Doors."""
import logging
import voluptuous as vol

from homeassistant.components.cover import (
    CoverDevice,
    PLATFORM_SCHEMA,
    SUPPORT_CLOSE,
    SUPPORT_OPEN,
)
from homeassistant.const import (
    CONF_PASSWORD,
    CONF_TYPE,
    CONF_USERNAME,
    STATE_CLOSED,
    STATE_CLOSING,
    STATE_OPEN,
    STATE_OPENING,
)
from homeassistant.helpers import aiohttp_client, config_validation as cv

_LOGGER = logging.getLogger(__name__)

MYQ_TO_HASS = {
    "closed": STATE_CLOSED,
    "closing": STATE_CLOSING,
    "open": STATE_OPEN,
    "opening": STATE_OPENING,
}

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Required(CONF_TYPE): cv.string,
        vol.Required(CONF_USERNAME): cv.string,
        vol.Required(CONF_PASSWORD): cv.string,
    }
)


async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
    """Set up the platform."""
    from pymyq import login
    from pymyq.errors import MyQError, UnsupportedBrandError

    websession = aiohttp_client.async_get_clientsession(hass)

    username = config[CONF_USERNAME]
    password = config[CONF_PASSWORD]
    brand = config[CONF_TYPE]

    try:
        myq = await login(username, password, brand, websession)
    except UnsupportedBrandError:
        _LOGGER.error("Unsupported brand: %s", brand)
        return
    except MyQError as err:
        _LOGGER.error("There was an error while logging in: %s", err)
        return

    devices = await myq.get_devices()
    async_add_entities([MyQDevice(device) for device in devices], True)


class MyQDevice(CoverDevice):
    """Representation of a MyQ cover."""

    def __init__(self, device):
        """Initialize with API object, device id."""
        self._device = device

    @property
    def device_class(self):
        """Define this cover as a garage door."""
        return "garage"

    @property
    def name(self):
        """Return the name of the garage door if any."""
        return self._device.name

    @property
    def is_closed(self):
        """Return true if cover is closed, else False."""
        return MYQ_TO_HASS.get(self._device.state) == STATE_CLOSED

    @property
    def is_closing(self):
        """Return if the cover is closing or not."""
        return MYQ_TO_HASS.get(self._device.state) == STATE_CLOSING

    @property
    def is_opening(self):
        """Return if the cover is opening or not."""
        return MYQ_TO_HASS.get(self._device.state) == STATE_OPENING

    @property
    def supported_features(self):
        """Flag supported features."""
        return SUPPORT_OPEN | SUPPORT_CLOSE

    @property
    def unique_id(self):
        """Return a unique, HASS-friendly identifier for this entity."""
        return self._device.device_id

    async def async_close_cover(self, **kwargs):
        """Issue close command to cover."""
        await self._device.close()

    async def async_open_cover(self, **kwargs):
        """Issue open command to cover."""
        await self._device.open()

    async def async_update(self):
        """Update status of cover."""
        await self._device.update()