# -*- coding: utf-8 -*-
import asyncio
import logging

import aiohttp
import aiojobs.aiohttp

from homehub_backend.defs import kServiceWeather
from homehub_backend.lib.services import BaseService, ServiceData

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


class WeatherService(BaseService):
    KIND = kServiceWeather
    API_KEY_SETTINGS_KEY = 'WEATHER_SERVICE_API_KEY'
    API_URL = 'https://api.openweathermap.org/data/2.5/weather'

    def __init__(self, app, instance, characteristics):
        super(WeatherService, self).__init__(app, instance, characteristics)
        self._current_data = None

        self.api_key = None
        self.job = None
        self.session = None

    async def update_weather(self):
        LOGGER.debug('WeatherService.update_weather(): {city}'.format(
            city=self.characteristics['city'],
        ))

        params = {
            'APPID': self.api_key,
            'q': self.characteristics['city'],
            'units': self.characteristics['units'],
        }

        result = ServiceData()

        response = None
        try:
            response = await self.session.get(self.API_URL, params=params)
            if response.status != 200:
                raise RuntimeError('HTTP {status} {reason}'.format(
                    status=response.status,
                    reason=response.reason,
                ))
            else:
                result.data = await response.json()
        except Exception as exc:
            LOGGER.error('Unhandled exception!', exc_info=exc)
            result.exception = exc
        finally:
            if response:
                response.release()

        self._current_data = result

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

        return self._current_data

    async def worker(self):
        while True:
            await asyncio.sleep(60 * 10)
            await self.update_weather()
            await self.notify()

            if self.job.closed:
                break

    async def start(self):
        LOGGER.debug('WeatherService.start()')

        self.api_key = getattr(
            self.app['SETTINGS'], self.API_KEY_SETTINGS_KEY, None,
        )
        assert self.api_key is not None, 'API key is missing'

        assert self.characteristics['city'] is not None, 'City is missing'
        assert self.characteristics['city'] != '', 'City is empty'

        if not self.session:
            self.session = aiohttp.ClientSession()

        if not self._current_data:
            await self.update_weather()

        if not self.job:
            scheduler = aiojobs.aiohttp.get_scheduler_from_app(self.app)
            self.job = await scheduler.spawn(self.worker())

    async def stop(self):
        LOGGER.debug('WeatherService.stop()')

        if self.session and not self.session.closed:
            await self.session.close()

        if self.job is not None and not self.job.closed:
            await self.job.close()
