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

"""Cloud Endpoints API request-related data and functions."""

from __future__ import absolute_import

# pylint: disable=g-bad-name
import copy
import json
import logging
from six.moves import urllib
import zlib

from . import util

_logger = logging.getLogger(__name__)

_METHOD_OVERRIDE = 'X-HTTP-METHOD-OVERRIDE'


class ApiRequest(object):
  """Simple data object representing an API request.

  Parses the request from environment variables into convenient pieces
  and stores them as members.
  """
  def __init__(self, environ, base_paths=None):
    """Constructor.

    Args:
      environ: An environ dict for the request as defined in PEP-333.

    Raises:
      ValueError: If the path for the request is invalid.
    """
    self.headers = util.get_headers_from_environ(environ)
    self.http_method = environ['REQUEST_METHOD']
    self.url_scheme = environ['wsgi.url_scheme']
    self.server = environ['SERVER_NAME']
    self.port = environ['SERVER_PORT']
    self.path = environ['PATH_INFO']
    self.request_uri = environ.get('REQUEST_URI')
    if self.request_uri is not None and len(self.request_uri) < len(self.path):
      self.request_uri = None
    self.query = environ.get('QUERY_STRING')
    self.body = environ['wsgi.input'].read()
    if self.body and self.headers.get('CONTENT-ENCODING') == 'gzip':
      # Increasing wbits to 16 + MAX_WBITS is necessary to be able to decode
      # gzipped content (as opposed to zlib-encoded content).
      # If there's an error in the decompression, it could be due to another
      # part of the serving chain that already decompressed it without clearing
      # the header. If so, just ignore it and continue.
      try:
        self.body = zlib.decompress(self.body, 16 + zlib.MAX_WBITS)
      except zlib.error:
        pass
    if _METHOD_OVERRIDE in self.headers:
      # the query arguments in the body will be handled by ._process_req_body()
      self.http_method = self.headers[_METHOD_OVERRIDE]
      del self.headers[_METHOD_OVERRIDE]  # wsgiref.headers.Headers doesn't implement .pop()
    self.source_ip = environ.get('REMOTE_ADDR')
    self.relative_url = self._reconstruct_relative_url(environ)

    if not base_paths:
      base_paths = set()
    elif isinstance(base_paths, list):
      base_paths = set(base_paths)

    # Find a base_path in the path
    for base_path in base_paths:
      if self.path.startswith(base_path):
        self.path = self.path[len(base_path):]
        if self.request_uri is not None:
          self.request_uri = self.request_uri[len(base_path):]
        self.base_path = base_path
        break
    else:
      raise ValueError('Invalid request path: %s' % self.path)

    if self.query:
      self.parameters = urllib.parse.parse_qs(self.query, keep_blank_values=True)
    else:
      self.parameters = {}
    self.body_json = self._process_req_body(self.body) if self.body else {}
    self.request_id = None

    # Check if it's a batch request.  We'll only handle single-element batch
    # requests on the dev server (and we need to handle them because that's
    # what RPC and JS calls typically show up as).  Pull the request out of the
    # list and record the fact that we're processing a batch.
    if isinstance(self.body_json, list):
      if len(self.body_json) != 1:
        _logger.warning('Batch requests with more than 1 element aren\'t '
                        'supported in devappserver2.  Only the first element '
                        'will be handled.  Found %d elements.',
                        len(self.body_json))
      else:
        _logger.info('Converting batch request to single request.')
      self.body_json = self.body_json[0]
      self.body = json.dumps(self.body_json)
      self._is_batch = True
    else:
      self._is_batch = False

  def _process_req_body(self, body):
    """Process the body of the HTTP request.

    If the body is valid JSON, return the JSON as a dict.
    Else, convert the key=value format to a dict and return that.

    Args:
      body: The body of the HTTP request.
    """
    try:
      return json.loads(body)
    except ValueError:
      return urllib.parse.parse_qs(body, keep_blank_values=True)

  def _reconstruct_relative_url(self, environ):
    """Reconstruct the relative URL of this request.

    This is based on the URL reconstruction code in Python PEP 333:
    http://www.python.org/dev/peps/pep-0333/#url-reconstruction.  Rebuild the
    URL from the pieces available in the environment.

    Args:
      environ: An environ dict for the request as defined in PEP-333

    Returns:
      The portion of the URL from the request after the server and port.
    """
    url = urllib.parse.quote(environ.get('SCRIPT_NAME', ''))
    url += urllib.parse.quote(environ.get('PATH_INFO', ''))
    if environ.get('QUERY_STRING'):
      url += '?' + environ['QUERY_STRING']
    return url

  def reconstruct_hostname(self, port_override=None):
    """Reconstruct the hostname of a request.

    This is based on the URL reconstruction code in Python PEP 333:
    http://www.python.org/dev/peps/pep-0333/#url-reconstruction.  Rebuild the
    hostname from the pieces available in the environment.

    Args:
      port_override: str, An override for the port on the returned hostname.

    Returns:
      The hostname portion of the URL from the request, not including the
      URL scheme.
    """
    url = self.server
    port = port_override or self.port
    if port and ((self.url_scheme == 'https' and str(port) != '443') or
                 (self.url_scheme != 'https' and str(port) != '80')):
      url += ':{0}'.format(port)

    return url

  def reconstruct_full_url(self, port_override=None):
    """Reconstruct the full URL of a request.

    This is based on the URL reconstruction code in Python PEP 333:
    http://www.python.org/dev/peps/pep-0333/#url-reconstruction.  Rebuild the
    hostname from the pieces available in the environment.

    Args:
      port_override: str, An override for the port on the returned full URL.

    Returns:
      The full URL from the request, including the URL scheme.
    """
    return '{0}://{1}{2}'.format(self.url_scheme,
                                  self.reconstruct_hostname(port_override),
                                  self.relative_url)

  def copy(self):
    return copy.deepcopy(self)

  def is_batch(self):
    return self._is_batch
