#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# 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 with_statement




import cgi
import copy
import json
import logging
import urllib

from google.appengine.tools.devappserver2 import util


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

  Parses the request from environment variables into convenient pieces
  and stores them as members.
  """
  _API_PREFIX = '/_ah/api/'

  def __init__(self, environ):
    """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.server = environ['SERVER_NAME']
    self.port = environ['SERVER_PORT']
    self.path = environ['PATH_INFO']
    self.query = environ.get('QUERY_STRING')
    self.body = environ['wsgi.input'].read()
    self.source_ip = environ.get('REMOTE_ADDR')
    self.relative_url = self._reconstruct_relative_url(environ)

    if not self.path.startswith(self._API_PREFIX):
      raise ValueError('Invalid request path: %s' % self.path)
    self.path = self.path[len(self._API_PREFIX):]
    if self.query:
      self.parameters = cgi.parse_qs(self.query, keep_blank_values=True)
    else:
      self.parameters = {}
    self.body_json = json.loads(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:
        logging.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:
        logging.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 _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.quote(environ.get('SCRIPT_NAME', ''))
    url += urllib.quote(environ.get('PATH_INFO', ''))
    if environ.get('QUERY_STRING'):
      url += '?' + environ['QUERY_STRING']
    return url

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

  def is_rpc(self):
    # Google's JsonRPC protocol creates a handler at /rpc for any Cloud
    # Endpoints API, with api name, version, and method name being in the
    # body of the request.
    # If the request is sent to /rpc, we will treat it as JsonRPC.
    # The client libraries for iOS's Objective C use RPC and not the REST
    # versions of the API.
    return self.path == 'rpc'

  def is_batch(self):
    return self._is_batch
