"""
Component of the move bot that will load up the data from the update service.
"""
import moves
from rdflib.namespace import Namespace, FOAF
from rhobot.namespace import RHO
from rhobot.components.storage import StoragePayload
from sleekxmpp.plugins.base import base_plugin
from rhobot.components.configuration import BotConfiguration
from move_bot.components.configuration_enums import CLIENT_SECRET_KEY, IDENTIFIER_KEY, CLIENT_TOKEN_KEY
from move_bot.components.update_service.process_segment import ProcessSegment
import logging


logger = logging.getLogger(__name__)
WGS84_POS_NAMESPACE = Namespace('http://www.w3.org/2003/01/geo/wgs84_pos#')


class UpdateService(base_plugin):
    """
    Service that will create a group of promises that can be used to insert the data from the moves-app.com API.
    """

    name = 'update_service'
    description = 'Service that will update data store from move api'
    dependencies = {'rho_bot_storage_client', 'rho_bot_configuration', 'rho_bot_rdf_publish',
                    'rho_bot_representation_manager', }

    _delay = 600.0
    _past_days = 31

    def plugin_init(self):
        """
        Initialize the plugin.
        :return:
        """
        self.xmpp.add_event_handler(BotConfiguration.CONFIGURATION_RECEIVED_EVENT, self._configuration_updated)

    def post_init(self):
        super(UpdateService, self).post_init()

        self._storage_client = self.xmpp['rho_bot_storage_client']
        self._scheduler = self.xmpp['rho_bot_scheduler']
        self._configuration = self.xmpp['rho_bot_configuration']
        self._rdf_publish = self.xmpp['rho_bot_rdf_publish']

    def fetch_for_month(self, date):
        """
        Fetch data from the moves api for the month provided.
        :param date: datetime.date object
        :return: promise
        """
        promise = self._scheduler.defer(self._create_session)
        promise = promise.then(self._build_client)
        promise = promise.then(self._get_owner)
        promise = promise.then(self._scheduler.generate_promise_handler(self._get_month_data, date))
        promise = promise.then(self._process_data)

        return promise

    def _configuration_updated(self, *args, **kwargs):
        """
        Callback when the configuration details have been received by the bot.
        :param args:
        :param kwargs:
        :return:
        """
        logger.debug('Rescheduling task for time: %s' % self._delay)
        self._scheduler.schedule_task(self._start, delay=self._delay, repeat=False)

    def _start(self):
        """
        Entry point.

        Generates the basic chain of promises that will be used.  Each of the promises should return the session
        variable that will be updated by all of the individual tasks so that each of the following tasks will have
        access to all of the work that has been done before it.
        :return:
        """
        promise = self._scheduler.defer(self._create_session)
        promise = promise.then(self._build_client)
        promise = promise.then(self._get_owner)
        promise = promise.then(self._get_data)
        promise = promise.then(self._process_data)

        # Reschedule the whole thing again
        promise.then(self._configuration_updated, self._configuration_updated)

    def _create_session(self):
        """
        Creates the session variable that will be used throughout all of the promises.
        :return: session dictionary
        """
        logger.debug('Creating session')
        return dict()