# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Module to implement the JSON-RPC protocol.

This module uses xmlrpclib as the base and only overrides those
portions that implement the XML-RPC protocol. These portions are rewritten
to use the JSON-RPC protocol instead.

When large portions of code need to be rewritten the original code and
comments are preserved. The intention here is to keep the amount of code
change to a minimum.

This module only depends on default Python modules. No third party code is
required to use this module.
"""
import json
import urllib
import xmlrpclib as _base

__version__ = '1.0.0'
gzip_encode = _base.gzip_encode


class Error(Exception):

  def __str__(self):
    return repr(self)


class ProtocolError(Error):
  """Indicates a JSON protocol error."""

  def __init__(self, url, errcode, errmsg, headers):
    Error.__init__(self)
    self.url = url
    self.errcode = errcode
    self.errmsg = errmsg
    self.headers = headers

  def __repr__(self):
    return (
        '<ProtocolError for %s: %s %s>' %
        (self.url, self.errcode, self.errmsg))


class ResponseError(Error):
  """Indicates a broken response package."""
  pass


class Fault(Error):
  """Indicates an JSON-RPC fault package."""

  def __init__(self, code, message):
    Error.__init__(self)
    if not isinstance(code, int):
      raise ProtocolError('Fault code must be an integer.')
    self.code = code
    self.message = message

  def __repr__(self):
      return (
          '<Fault %s: %s>' %
          (self.code, repr(self.message))
          )


def CreateRequest(methodname, params, ident=''):
  """Create a valid JSON-RPC request.

  Args:
    methodname: The name of the remote method to invoke.
    params: The parameters to pass to the remote method. This should be a
        list or tuple and able to be encoded by the default JSON parser.

  Returns:
    A valid JSON-RPC request object.
  """
  request = {
      'jsonrpc': '2.0',
      'method': methodname,
      'params': params,
      'id': ident
      }

  return request


def CreateRequestString(methodname, params, ident=''):
  """Create a valid JSON-RPC request string.

  Args:
    methodname: The name of the remote method to invoke.
    params: The parameters to pass to the remote method.
        These parameters need to be encode-able by the default JSON parser.
    ident: The request identifier.

  Returns:
    A valid JSON-RPC request string.
  """
  return json.dumps(CreateRequest(methodname, params, ident))

def CreateResponse(data, ident):
  """Create a JSON-RPC response.

  Args:
    data: The data to return.
    ident: The response identifier.

  Returns:
    A valid JSON-RPC response object.
  """
  if isinstance(data, Fault):
    response = {
        'jsonrpc': '2.0',
        'error': {
            'code': data.code,
            'message': data.message},
        'id': ident
        }
  else:
    response = {
        'jsonrpc': '2.0',
        'response': data,
        'id': ident
        }

  return response


def CreateResponseString(data, ident):
  """Create a JSON-RPC response string.

  Args:
    data: The data to return.
    ident: The response identifier.

  Returns:
    A valid JSON-RPC response object.
  """
  return json.dumps(CreateResponse(data, ident))


def ParseHTTPResponse(response):
  """Parse an HTTP response object and return the JSON object.

  Args:
    response: An HTTP response object.

  Returns:
    The returned JSON-RPC object.

  Raises:
    ProtocolError: if the object format is not correct.
    Fault: If a Fault error is returned from the server.
  """
  # Check for new http response object, else it is a file object
  if hasattr(response, 'getheader'):
    if response.getheader('Content-Encoding', '') == 'gzip':
      stream = _base.GzipDecodedResponse(response)
    else:
      stream = response
  else:
    stream = response

  data = ''
  while 1:
    chunk = stream.read(1024)
    if not chunk:
      break
    data += chunk

  response = json.loads(data)
  ValidateBasicJSONRPCData(response)

  if 'response' in response:
    ValidateResponse(response)
    return response['response']
  elif 'error' in response:
    ValidateError(response)
    code = response['error']['code']
    message = response['error']['message']
    raise Fault(code, message)
  else:
    raise ProtocolError('No valid JSON returned')


def ValidateRequest(data):
  """Validate a JSON-RPC request object.

  Args:
    data: The JSON-RPC object (dict).

  Raises:
    ProtocolError: if the object format is not correct.
  """
  ValidateBasicJSONRPCData(data)
  if 'method' not in data or 'params' not in data:
    raise ProtocolError('JSON is not a valid request')


def ValidateResponse(data):
  """Validate a JSON-RPC response object.

  Args:
    data: The JSON-RPC object (dict).

  Raises:
    ProtocolError: if the object format is not correct.
  """
  ValidateBasicJSONRPCData(data)
  if 'response' not in data:
    raise ProtocolError('JSON is not a valid response')


def ValidateError(data):
  """Validate a JSON-RPC error object.

  Args:
    data: The JSON-RPC object (dict).

  Raises:
    ProtocolError: if the object format is not correct.
  """
  ValidateBasicJSONRPCData(data)
  if ('error' not in data or
      'code' not in data['error'] or
      'message' not in data['error']):
    raise ProtocolError('JSON is not a valid error response')


def ValidateBasicJSONRPCData(data):
  """Validate a basic JSON-RPC object.

  Args:
    data: The JSON-RPC object (dict).

  Raises:
    ProtocolError: if the object format is not correct.
  """
  error = None
  if not isinstance(data, dict):
    error = 'JSON data is not a dictionary'
  elif 'jsonrpc' not in data or data['jsonrpc'] != '2.0':
    error = 'JSON is not a valid JSON RPC 2.0 message'
  elif 'id' not in data:
    error = 'JSON data missing required id entry'
  if error:
    raise ProtocolError(error)


class Transport(_base.Transport):
  """RPC transport class.

  This class extends the functionality of xmlrpclib.Transport and only
  overrides the operations needed to change the protocol from XML-RPC to
  JSON-RPC.
  """

  user_agent = 'jsonrpclib.py/' + __version__

  def send_content(self, connection, request_body):
    """Send the request."""
    connection.putheader('Content-Type','application/json')

    #optionally encode the request
    if (self.encode_threshold is not None and
        self.encode_threshold < len(request_body) and
        gzip):
      connection.putheader('Content-Encoding', 'gzip')
      request_body = gzip_encode(request_body)

    connection.putheader('Content-Length', str(len(request_body)))
    connection.endheaders(request_body)

  def single_request(self, host, handler, request_body, verbose=0):
    """Issue a single JSON-RPC request."""

    h = self.make_connection(host)
    if verbose:
      h.set_debuglevel(1)
    try:
      self.send_request(h, handler, request_body)
      self.send_host(h, host)
      self.send_user_agent(h)
      self.send_content(h, request_body)

      response = h.getresponse(buffering=True)
      if response.status == 200:
        self.verbose = verbose

        return self.parse_response(response)

    except Fault:
      raise
    except Exception:
      # All unexpected errors leave connection in
      # a strange state, so we clear it.
      self.close()
      raise

    # discard any response data and raise exception
    if response.getheader('content-length', 0):
      response.read()
    raise ProtocolError(
        host + handler,
        response.status, response.reason,
        response.msg,
        )

  def parse_response(self, response):
    """Parse the HTTP resoponse from the server."""
    return ParseHTTPResponse(response)


class SafeTransport(_base.SafeTransport):
  """Transport class for HTTPS servers.

  This class extends the functionality of xmlrpclib.SafeTransport and only
  overrides the operations needed to change the protocol from XML-RPC to
  JSON-RPC.
  """

  def parse_response(self, response):
    return ParseHTTPResponse(response)


class ServerProxy(_base.ServerProxy):
  """Proxy class to the RPC server.

  This class extends the functionality of xmlrpclib.ServerProxy and only
  overrides the operations needed to change the protocol from XML-RPC to
  JSON-RPC.
  """

  def __init__(self, uri, transport=None, encoding=None, verbose=0,
               allow_none=0, use_datetime=0):
    urltype, _ = urllib.splittype(uri)
    if urltype not in ('http', 'https'):
      raise IOError('unsupported JSON-RPC protocol')

    _base.ServerProxy.__init__(self, uri, transport, encoding, verbose,
                               allow_none, use_datetime)

    if transport is None:
      if type == 'https':
        transport = SafeTransport(use_datetime=use_datetime)
      else:
        transport = Transport(use_datetime=use_datetime)
    self.__transport = transport

  def __request(self, methodname, params):
    """Call a method on the remote server."""
    request = CreateRequestString(methodname, params)

    response = self.__transport.request(
        self.__host,
        self.__handler,
        request,
        verbose=self.__verbose
        )

    return response
