import logging

from jaraco.collections import DictAdapter, Projection

from ._itertools import single

log = logging.getLogger(__name__)


class Stateful:
    def __init__(self, state, client):
        """Set up Abode device."""
        self._state = state
        self._client = client

    def __getattr__(self, name):
        try:
            return self._state[name]
        except KeyError as exc:
            raise AttributeError(name) from exc

    def update(self, state):
        """Update the local state from a new state.

        Only updates keys already present.
        """
        self._state.update(Projection(self._state, state))

    @property
    def desc(self):
        """Return a short description of self."""
        return self._desc_t.format_map(DictAdapter(self))

    def refresh(self, path=None):
        """Refresh the device state.

        Useful when not using the notification service.
        """
        tmpl = path or self._url_t
        path = tmpl.format(id=self.id)

        response = self._client.send_request(method="get", path=path)
        state = single(response.json())

        log.debug(f"{self.__class__.__name__} Refresh Response: %s", response.text)

        self._validate(state)
        self.update(state)

        return state

    def _validate(self, state):
        pass
