import hashlib
import hmac

from json_import import simplejson


class SubscriptionType:
    TAG = 'tag'
    USER = 'user'
    GEOGRAPHY = 'geography'
    LOCATION = 'location'


class SubscriptionError(Exception):
    pass


class SubscriptionVerifyError(SubscriptionError):
    pass


class SubscriptionsReactor(object):

    callbacks = {}

    def _process_update(self, update):
        object_callbacks = self.callbacks.get(update['object'], [])

        for callback in object_callbacks:
            callback(update)

    def process(self, client_secret, raw_response, x_hub_signature):
        if not self._verify_signature(client_secret, raw_response, x_hub_signature):
            raise SubscriptionVerifyError("X-Hub-Signature and hmac digest did not match")

        try:
            response = simplejson.loads(raw_response)
        except ValueError:
            raise SubscriptionError('Unable to parse response, not valid JSON.')

        for update in response:
            self._process_update(update)

    def register_callback(self, object_type, callback):
        cb_list = self.callbacks.get(object_type, [])

        if callback not in cb_list:
            cb_list.append(callback)
            self.callbacks[object_type] = cb_list

    def deregister_callback(self, object_type, callback):
        callbacks = self.callbacks.get(object_type, [])
        callbacks.remove(callback)

    def _verify_signature(self, client_secret, raw_response, x_hub_signature):
        digest = hmac.new(client_secret.encode('utf-8'),
                          msg=raw_response.encode('utf-8'),
                          digestmod=hashlib.sha1
                          ).hexdigest()
        return digest == x_hub_signature
