# -*- coding: utf8 -*-
import datetime
import json
import logging
import uuid

import gmqtt

from homehub_backend.lib.services import BaseService, ServiceData
from homehub_iformicarium.defs import kServiceIFormicarium

LOGGER = logging.getLogger('homehub.tradfri.services')


class iFormicariumService(BaseService):
    KIND = kServiceIFormicarium

    def __init__(self, app, instance, characteristics):
        super(iFormicariumService, self).__init__(
            app, instance, characteristics,
        )

        self._current_data = None

        self.client = None

    async def current_data(self):
        if self._current_data is None:
            return ServiceData()

        return self._current_data

    def on_client_connect(self, client, flags, rc, properties):
        LOGGER.debug('iFormicariumService.on_client_connect()')
        client.subscribe(self.characteristics['topic'])

    def on_client_disconnect(self, client, packet, exc=None):
        LOGGER.debug(
            'iFormicariumService.on_client_disconnect()', exc_info=exc,
        )

    async def on_client_message(self, client, topic, payload, qos, properties):
        LOGGER.debug('iFormicariumService.on_client_message() {topic} "{payload}"'.format(
            topic=topic,
            payload=payload,
        ))

        result = ServiceData()

        should_notify = True
        try:
            message = json.loads(payload)
            should_notify = message['name'] == self.characteristics['name']
            result.data = message
            result.data['dt'] = datetime.datetime.now().timestamp()
        except Exception as exc:
            LOGGER.error('Unhandled exception!', exc_info=exc)
            result.exception = exc

        if should_notify:
            self._current_data = result
            await self.notify()

    async def start(self):
        if not self.client:
            self.client = gmqtt.Client(str(uuid.uuid4()))
            self.client.set_config({'reconnect_retries': 10})
            self.client.on_connect = self.on_client_connect
            self.client.on_disconnect = self.on_client_disconnect
            self.client.on_message = self.on_client_message

            await self.client.connect(self.characteristics['mqtt'])

    async def stop(self):
        if self.client and self.client.is_connected:
            await self.client.disconnect()
