# 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.

"""Model objects for requests and responses.

Each API may support one or more serializations, such
as JSON, Atom, etc. The model classes are responsible
for converting between the wire format and the Python
object representation.
"""
from __future__ import absolute_import
import six

__author__ = "jcgregorio@google.com (Joe Gregorio)"

import json
import logging
import platform
import pkg_resources

from six.moves.urllib.parse import urlencode

from googleapiclient.errors import HttpError

_LIBRARY_VERSION = pkg_resources.get_distribution("google-api-python-client").version
_PY_VERSION = platform.python_version()

LOGGER = logging.getLogger(__name__)

dump_request_response = False


def _abstract():
    raise NotImplementedError("You need to override this function")


class Model(object):
    """Model base class.

  All Model classes should implement this interface.
  The Model serializes and de-serializes between a wire
  format such as JSON and a Python object representation.
  """

    def request(self, headers, path_params, query_params, body_value):
        """Updates outgoing requests with a serialized body.

    Args:
      headers: dict, request headers
      path_params: dict, parameters that appear in the request path
      query_params: dict, parameters that appear in the query
      body_value: object, the request body as a Python object, which must be
                  serializable.
    Returns:
      A tuple of (headers, path_params, query, body)

      headers: dict, request headers
      path_params: dict, parameters that appear in the request path
      query: string, query part of the request URI
      body: string, the body serialized in the desired wire format.
    """
        _abstract()

    def response(self, resp, content):
        """Convert the response wire format into a Python object.

    Args:
      resp: httplib2.Response, the HTTP response headers and status
      content: string, the body of the HTTP response

    Returns:
      The body de-serialized as a Python object.

    Raises:
      googleapiclient.errors.HttpError if a non 2xx response is received.
    """
        _abstract()


class BaseModel(Model):
    """Base model class.

  Subclasses should provide implementations for the "serialize" and
  "deserialize" methods, as well as values for the following class attributes.

  Attributes:
    accept: The value to use for the HTTP Accept header.
    content_type: The value to use for the HTTP Content-type header.
    no_content_response: The value to return when deserializing a 204 "No
        Content" response.
    alt_param: The value to supply as the "alt" query parameter for requests.
  """

    accept = None
    content_type = None
    no_content_response = None
    alt_param = None

    def _log_request(self, headers, path_params, query, body):
        """Logs debugging information about the request if requested."""
        if dump_request_response:
            LOGGER.info("--request-start--")
            LOGGER.info("-headers-start-")
            for h, v in six.iteritems(headers):
                LOGGER.info("%s: %s", h, v)
            LOGGER.info("-headers-end-")
            LOGGER.info("-path-parameters-start-")
            for h, v in six.iteritems(path_params):
                LOGGER.info("%s: %s", h, v)
            LOGGER.info("-path-parameters-end-")
            LOGGER.info("body: %s", body)
            LOGGER.info("query: %s", query)
            LOGGER.info("--request-end--")

    def request(self, headers, path_params, query_params, body_value):
        """Updates outgoing requests with a serialized body.

    Args:
      headers: dict, request headers
      path_params: dict, parameters that appear in the request path
      query_params: dict, parameters that appear in the query
      body_value: object, the request body as a Python object, which must be
                  serializable by json.
    Returns:
      A tuple of (headers, path_params, query, body)

      headers: dict, request headers
      path_params: dict, parameters that appear in the request path
      query: string, query part of the request URI
      body: string, the body serialized as JSON
    """
        query = self._build_query(query_params)
        headers["accept"] = self.accept
        headers["accept-encoding"] = "gzip, deflate"
        if "user-agent" in headers:
            headers["user-agent"] += " "
        else:
            headers["user-agent"] = ""
        headers["user-agent"] += "(gzip)"
        if "x-goog-api-client" in headers:
            headers["x-goog-api-client"] += " "
        else:
            headers["x-goog-api-client"] = ""
        headers["x-goog-api-client"] += "gdcl/%s gl-python/%s" % (
            _LIBRARY_VERSION,
            _PY_VERSION,
        )

        if body_value is not None:
            headers["content-type"] = self.content_type
            body_value = self.serialize(body_value)
        self._log_request(headers, path_params, query, body_value)
        return (headers, path_params, query, body_value)

    def _build_query(self, params):
        """Builds a query string.

    Args:
      params: dict, the query parameters

    Returns:
      The query parameters properly encoded into an HTTP URI query string.
    """
        if self.alt_param is not None:
            params.update({"alt": self.alt_param})
        astuples = []
        for key, value in six.iteritems(params):
            if type(value) == type([]):
                for x in value:
                    x = x.encode("utf-8")
                    astuples.append((key, x))
            else:
                if isinstance(value, six.text_type) and callable(value.encode):
                    value = value.encode("utf-8")
                astuples.append((key, value))
        return "?" + urlencode(astuples)

    def _log_response(self, resp, content):
        """Logs debugging information about the response if requested."""
        if dump_request_response:
            LOGGER.info("--response-start--")
            for h, v in six.iteritems(resp):
                LOGGER.info("%s: %s", h, v)
            if content:
                LOGGER.info(content)
            LOGGER.info("--response-end--")

    def response(self, resp, content):
        """Convert the response wire format into a Python object.

    Args:
      resp: httplib2.Response, the HTTP response headers and status
      content: string, the body of the HTTP response

    Returns:
      The body de-serialized as a Python object.

    Raises:
      googleapiclient.errors.HttpError if a non 2xx response is received.
    """
        self._log_response(resp, content)
        # Error handling is TBD, for example, do we retry
        # for some operation/error combinations?
        if resp.status < 300:
            if resp.status == 204:
                # A 204: No Content response should be treated differently
                # to all the other success states
                return self.no_content_response
            return self.deserialize(content)
        else:
            LOGGER.debug("Content from bad request was: %r" % content)
            raise HttpError(resp, content)

    def serialize(self, body_value):
        """Perform the actual Python object serialization.

    Args:
      body_value: object, the request body as a Python object.

    Returns:
      string, the body in serialized form.
    """
        _abstract()

    def deserialize(self, content):
        """Perform the actual deserialization from response string to Python
    object.

    Args:
      content: string, the body of the HTTP response

    Returns:
      The body de-serialized as a Python object.
    """
        _abstract()


class JsonModel(BaseModel):
    """Model class for JSON.

  Serializes and de-serializes between JSON and the Python
  object representation of HTTP request and response bodies.
  """

    accept = "application/json"
    content_type = "application/json"
    alt_param = "json"

    def __init__(self, data_wrapper=False):
        """Construct a JsonModel.

    Args:
      data_wrapper: boolean, wrap requests and responses in a data wrapper
    """
        self._data_wrapper = data_wrapper

    def serialize(self, body_value):
        if (
            isinstance(body_value, dict)
            and "data" not in body_value
            and self._data_wrapper
        ):
            body_value = {"data": body_value}
        return json.dumps(body_value)

    def deserialize(self, content):
        try:
            content = content.decode("utf-8")
        except AttributeError:
            pass
        body = json.loads(content)
        if self._data_wrapper and isinstance(body, dict) and "data" in body:
            body = body["data"]
        return body

    @property
    def no_content_response(self):
        return {}


class RawModel(JsonModel):
    """Model class for requests that don't return JSON.

  Serializes and de-serializes between JSON and the Python
  object representation of HTTP request, and returns the raw bytes
  of the response body.
  """

    accept = "*/*"
    content_type = "application/json"
    alt_param = None

    def deserialize(self, content):
        return content

    @property
    def no_content_response(self):
        return ""


class MediaModel(JsonModel):
    """Model class for requests that return Media.

  Serializes and de-serializes between JSON and the Python
  object representation of HTTP request, and returns the raw bytes
  of the response body.
  """

    accept = "*/*"
    content_type = "application/json"
    alt_param = "media"

    def deserialize(self, content):
        return content

    @property
    def no_content_response(self):
        return ""


class ProtocolBufferModel(BaseModel):
    """Model class for protocol buffers.

  Serializes and de-serializes the binary protocol buffer sent in the HTTP
  request and response bodies.
  """

    accept = "application/x-protobuf"
    content_type = "application/x-protobuf"
    alt_param = "proto"

    def __init__(self, protocol_buffer):
        """Constructs a ProtocolBufferModel.

    The serialized protocol buffer returned in an HTTP response will be
    de-serialized using the given protocol buffer class.

    Args:
      protocol_buffer: The protocol buffer class used to de-serialize a
      response from the API.
    """
        self._protocol_buffer = protocol_buffer

    def serialize(self, body_value):
        return body_value.SerializeToString()

    def deserialize(self, content):
        return self._protocol_buffer.FromString(content)

    @property
    def no_content_response(self):
        return self._protocol_buffer()


def makepatch(original, modified):
    """Create a patch object.

  Some methods support PATCH, an efficient way to send updates to a resource.
  This method allows the easy construction of patch bodies by looking at the
  differences between a resource before and after it was modified.

  Args:
    original: object, the original deserialized resource
    modified: object, the modified deserialized resource
  Returns:
    An object that contains only the changes from original to modified, in a
    form suitable to pass to a PATCH method.

  Example usage:
    item = service.activities().get(postid=postid, userid=userid).execute()
    original = copy.deepcopy(item)
    item['object']['content'] = 'This is updated.'
    service.activities.patch(postid=postid, userid=userid,
      body=makepatch(original, item)).execute()
  """
    patch = {}
    for key, original_value in six.iteritems(original):
        modified_value = modified.get(key, None)
        if modified_value is None:
            # Use None to signal that the element is deleted
            patch[key] = None
        elif original_value != modified_value:
            if type(original_value) == type({}):
                # Recursively descend objects
                patch[key] = makepatch(original_value, modified_value)
            else:
                # In the case of simple types or arrays we just replace
                patch[key] = modified_value
        else:
            # Don't add anything to patch if there's no change
            pass
    for key in modified:
        if key not in original:
            patch[key] = modified[key]

    return patch
