# 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


# 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 headers.items():
        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 CHANNEL_PARAMS.items():
            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,
    )
