# Copyright 2014 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Channel notifications support.

Classes and functions to support channel subscriptions and notifications
on those channels.

Notes:
  - This code is based on experimental APIs and is subject to change.
  - Notification does not do deduplication of notification ids, that's up to
    the receiver.
  - Storing the Channel between calls is up to the caller.


Example setting up a channel:

  # Create a new channel that gets notifications via webhook.
  channel = new_webhook_channel("https://example.com/my_web_hook")

  # Store the channel, keyed by 'channel.id'. Store it before calling the
  # watch method because notifications may start arriving before the watch
  # method returns.
  ...

  resp = service.objects().watchAll(
    bucket="some_bucket_id", body=channel.body()).execute()
  channel.update(resp)

  # Store the channel, keyed by 'channel.id'. Store it after being updated
  # since the resource_id value will now be correct, and that's needed to
  # stop a subscription.
  ...


An example Webhook implementation using webapp2. Note that webapp2 puts
headers in a case insensitive dictionary, as headers aren't guaranteed to
always be upper case.

  id = self.request.headers[X_GOOG_CHANNEL_ID]

  # Retrieve the channel by id.
  channel = ...

  # Parse notification from the headers, including validating the id.
  n = notification_from_headers(channel, self.request.headers)

  # Do app specific stuff with the notification here.
  if n.resource_state == 'sync':
    # Code to handle sync state.
  elif n.resource_state == 'exists':
    # Code to handle the exists state.
  elif n.resource_state == 'not_exists':
    # Code to handle the not exists state.


Example of unsubscribing.

  service.channels().stop(channel.body()).execute()
"""
from __future__ import absolute_import

import datetime
import uuid

from googleapiclient import errors
from googleapiclient import _helpers as util
import six


# The unix time epoch starts at midnight 1970.
EPOCH = datetime.datetime.utcfromtimestamp(0)

# Map the names of the parameters in the JSON channel description to
# the parameter names we use in the Channel class.
CHANNEL_PARAMS = {
    "address": "address",
    "id": "id",
    "expiration": "expiration",
    "params": "params",
    "resourceId": "resource_id",
    "resourceUri": "resource_uri",
    "type": "type",
    "token": "token",
}

X_GOOG_CHANNEL_ID = "X-GOOG-CHANNEL-ID"
X_GOOG_MESSAGE_NUMBER = "X-GOOG-MESSAGE-NUMBER"
X_GOOG_RESOURCE_STATE = "X-GOOG-RESOURCE-STATE"
X_GOOG_RESOURCE_URI = "X-GOOG-RESOURCE-URI"
X_GOOG_RESOURCE_ID = "X-GOOG-RESOURCE-ID"


def _upper_header_keys(headers):
    new_headers = {}
    for k, v in six.iteritems(headers):
        new_headers[k.upper()] = v
    return new_headers


class Notification(object):
    """A Notification from a Channel.

  Notifications are not usually constructed directly, but are returned
  from functions like notification_from_headers().

  Attributes:
    message_number: int, The unique id number of this notification.
    state: str, The state of the resource being monitored.
    uri: str, The address of the resource being monitored.
    resource_id: str, The unique identifier of the version of the resource at
      this event.
  """

    @util.positional(5)
    def __init__(self, message_number, state, resource_uri, resource_id):
        """Notification constructor.

    Args:
      message_number: int, The unique id number of this notification.
      state: str, The state of the resource being monitored. Can be one
        of "exists", "not_exists", or "sync".
      resource_uri: str, The address of the resource being monitored.
      resource_id: str, The identifier of the watched resource.
    """
        self.message_number = message_number
        self.state = state
        self.resource_uri = resource_uri
        self.resource_id = resource_id


class Channel(object):
    """A Channel for notifications.

  Usually not constructed directly, instead it is returned from helper
  functions like new_webhook_channel().

  Attributes:
    type: str, The type of delivery mechanism used by this channel. For
      example, 'web_hook'.
    id: str, A UUID for the channel.
    token: str, An arbitrary string associated with the channel that
      is delivered to the target address with each event delivered
      over this channel.
    address: str, The address of the receiving entity where events are
      delivered. Specific to the channel type.
    expiration: int, The time, in milliseconds from the epoch, when this
      channel will expire.
    params: dict, A dictionary of string to string, with additional parameters
      controlling delivery channel behavior.
    resource_id: str, An opaque id that identifies the resource that is
      being watched. Stable across different API versions.
    resource_uri: str, The canonicalized ID of the watched resource.
  """

    @util.positional(5)
    def __init__(
        self,
        type,
        id,
        token,
        address,
        expiration=None,
        params=None,
        resource_id="",
        resource_uri="",
    ):
        """Create a new Channel.

    In user code, this Channel constructor will not typically be called
    manually since there are functions for creating channels for each specific
    type with a more customized set of arguments to pass.

    Args:
      type: str, The type of delivery mechanism used by this channel. For
        example, 'web_hook'.
      id: str, A UUID for the channel.
      token: str, An arbitrary string associated with the channel that
        is delivered to the target address with each event delivered
        over this channel.
      address: str,  The address of the receiving entity where events are
        delivered. Specific to the channel type.
      expiration: int, The time, in milliseconds from the epoch, when this
        channel will expire.
      params: dict, A dictionary of string to string, with additional parameters
        controlling delivery channel behavior.
      resource_id: str, An opaque id that identifies the resource that is
        being watched. Stable across different API versions.
      resource_uri: str, The canonicalized ID of the watched resource.
    """
        self.type = type
        self.id = id
        self.token = token
        self.address = address
        self.expiration = expiration
        self.params = params
        self.resource_id = resource_id
        self.resource_uri = resource_uri

    def body(self):
        """Build a body from the Channel.

    Constructs a dictionary that's appropriate for passing into watch()
    methods as the value of body argument.

    Returns:
      A dictionary representation of the channel.
    """
        result = {
            "id": self.id,
            "token": self.token,
            "type": self.type,
            "address": self.address,
        }
        if self.params:
            result["params"] = self.params
        if self.resource_id:
            result["resourceId"] = self.resource_id
        if self.resource_uri:
            result["resourceUri"] = self.resource_uri
        if self.expiration:
            result["expiration"] = self.expiration

        return result

    def update(self, resp):
        """Update a channel with information from the response of watch().

    When a request is sent to watch() a resource, the response returned
    from the watch() request is a dictionary with updated channel information,
    such as the resource_id, which is needed when stopping a subscription.

    Args:
      resp: dict, The response from a watch() method.
    """
        for json_name, param_name in six.iteritems(CHANNEL_PARAMS):
            value = resp.get(json_name)
            if value is not None:
                setattr(self, param_name, value)


def notification_from_headers(channel, headers):
    """Parse a notification from the webhook request headers, validate
    the notification, and return a Notification object.

  Args:
    channel: Channel, The channel that the notification is associated with.
    headers: dict, A dictionary like object that contains the request headers
      from the webhook HTTP request.

  Returns:
    A Notification object.

  Raises:
    errors.InvalidNotificationError if the notification is invalid.
    ValueError if the X-GOOG-MESSAGE-NUMBER can't be converted to an int.
  """
    headers = _upper_header_keys(headers)
    channel_id = headers[X_GOOG_CHANNEL_ID]
    if channel.id != channel_id:
        raise errors.InvalidNotificationError(
            "Channel id mismatch: %s != %s" % (channel.id, channel_id)
        )
    else:
        message_number = int(headers[X_GOOG_MESSAGE_NUMBER])
        state = headers[X_GOOG_RESOURCE_STATE]
        resource_uri = headers[X_GOOG_RESOURCE_URI]
        resource_id = headers[X_GOOG_RESOURCE_ID]
        return Notification(message_number, state, resource_uri, resource_id)


@util.positional(2)
def new_webhook_channel(url, token=None, expiration=None, params=None):
    """Create a new webhook Channel.

    Args:
      url: str, URL to post notifications to.
      token: str, An arbitrary string associated with the channel that
        is delivered to the target address with each notification delivered
        over this channel.
      expiration: datetime.datetime, A time in the future when the channel
        should expire. Can also be None if the subscription should use the
        default expiration. Note that different services may have different
        limits on how long a subscription lasts. Check the response from the
        watch() method to see the value the service has set for an expiration
        time.
      params: dict, Extra parameters to pass on channel creation. Currently
        not used for webhook channels.
    """
    expiration_ms = 0
    if expiration:
        delta = expiration - EPOCH
        expiration_ms = (
            delta.microseconds / 1000 + (delta.seconds + delta.days * 24 * 3600) * 1000
        )
        if expiration_ms < 0:
            expiration_ms = 0

    return Channel(
        "web_hook",
        str(uuid.uuid4()),
        token,
        url,
        expiration=expiration_ms,
        params=params,
    )
