"""
Camera that loads a picture from a local file.

For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.verisure/
"""
import errno
import logging
import os

from homeassistant.components.camera import Camera
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.components.verisure import HUB as hub
from homeassistant.components.verisure import CONF_SMARTCAM

_LOGGER = logging.getLogger(__name__)


def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up the Verisure Camera."""
    if not int(hub.config.get(CONF_SMARTCAM, 1)):
        return False
    directory_path = hass.config.config_dir
    if not os.access(directory_path, os.R_OK):
        _LOGGER.error("file path %s is not readable", directory_path)
        return False
    hub.update_overview()
    smartcams = []
    smartcams.extend([
        VerisureSmartcam(hass, device_label, directory_path)
        for device_label in hub.get(
            "$.customerImageCameras[*].deviceLabel")])
    add_entities(smartcams)


class VerisureSmartcam(Camera):
    """Representation of a Verisure camera."""

    def __init__(self, hass, device_label, directory_path):
        """Initialize Verisure File Camera component."""
        super().__init__()

        self._device_label = device_label
        self._directory_path = directory_path
        self._image = None
        self._image_id = None
        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP,
                             self.delete_image)

    def camera_image(self):
        """Return image response."""
        self.check_imagelist()
        if not self._image:
            _LOGGER.debug("No image to display")
            return
        _LOGGER.debug("Trying to open %s", self._image)
        with open(self._image, 'rb') as file:
            return file.read()

    def check_imagelist(self):
        """Check the contents of the image list."""
        hub.update_smartcam_imageseries()
        image_ids = hub.get_image_info(
            "$.imageSeries[?(@.deviceLabel=='%s')].image[0].imageId",
            self._device_label)
        if not image_ids:
            return
        new_image_id = image_ids[0]
        if new_image_id in ('-1', self._image_id):
            _LOGGER.debug("The image is the same, or loading image_id")
            return
        _LOGGER.debug("Download new image %s", new_image_id)
        new_image_path = os.path.join(
            self._directory_path, '{}{}'.format(new_image_id, '.jpg'))
        hub.session.download_image(
            self._device_label, new_image_id, new_image_path)
        _LOGGER.debug("Old image_id=%s", self._image_id)
        self.delete_image(self)

        self._image_id = new_image_id
        self._image = new_image_path

    def delete_image(self, event):
        """Delete an old image."""
        remove_image = os.path.join(
            self._directory_path, '{}{}'.format(self._image_id, '.jpg'))
        try:
            os.remove(remove_image)
            _LOGGER.debug("Deleting old image %s", remove_image)
        except OSError as error:
            if error.errno != errno.ENOENT:
                raise

    @property
    def name(self):
        """Return the name of this camera."""
        return hub.get_first(
            "$.customerImageCameras[?(@.deviceLabel=='%s')].area",
            self._device_label)
