# -*- coding: utf-8 -*-
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Utilities for requesting information for a gerrit server via https.

https://gerrit-review.googlesource.com/Documentation/rest-api.html
"""

from __future__ import print_function

import HTMLParser
import base64
import cookielib
import datetime
import httplib
import json
import netrc
import os
import re
import socket
import sys
import urllib
import urlparse
import warnings
from cStringIO import StringIO

import httplib2
try:
  from oauth2client import gce
except ImportError:  # Newer oauth2client versions put it in .contrib
  # pylint: disable=import-error,no-name-in-module
  from oauth2client.contrib import gce

from chromite.lib import constants
from chromite.lib import cros_logging as logging
from chromite.lib import git
from chromite.lib import retry_util
from chromite.lib import timeout_util
from chromite.lib import cros_build_lib


_GAE_VERSION = 'GAE_VERSION'


class ErrorParser(HTMLParser.HTMLParser):
  """Class to parse GOB error message reported as HTML.

  Only data inside <div id='af-error-container'> section is retrieved from the
  GOB error message. Retrieved data is processed as follows:

  - newlines are removed
  - each <br> tag is replaced with '\n'
  - each <p> tag is replaced with '\n\n'
  """

  def __init__(self):
    HTMLParser.HTMLParser.__init__(self)
    self.in_div = False
    self.err_data = ''

  def handle_starttag(self, tag, attrs):
    tag_id = [x[1] for x in attrs if x[0] == 'id']
    if tag == 'div' and tag_id and tag_id[0] == 'af-error-container':
      self.in_div = True
      return

    if self.in_div:
      if tag == 'p':
        self.err_data += '\n\n'
        return

      if tag == 'br':
        self.err_data += '\n'
        return

  def handle_endtag(self, tag):
    if tag == 'div':
      self.in_div = False

  def handle_data(self, data):
    if self.in_div:
      self.err_data += data.replace('\n', '')

  def ParsedDiv(self):
    return self.err_data.strip()


@cros_build_lib.Memoize
def _GetNetRC():
  try:
    return netrc.netrc(None)
  except (IOError, netrc.NetrcParseError):
    try:
      return netrc.netrc(os.devnull)
    except IOError:
      return None


def _NetRCAuthenticators(host):
  """Returns the authenticators, if any, for the given |host|.

  Args:
    host: A hostname
  """
  net_rc = _GetNetRC()
  if net_rc:
    return net_rc.authenticators(host)


@cros_build_lib.Memoize
def _GetAppCredentials():
  """Returns the singleton Appengine credentials for gerrit code review."""
  return gce.AppAssertionCredentials(
      scope='https://www.googleapis.com/auth/gerritcodereview')


TRY_LIMIT = 10
SLEEP = 0.5
REQUEST_TIMEOUT_SECONDS = 120  # 2 minutes.

# Controls the transport protocol used to communicate with Gerrit servers using
# git. This is parameterized primarily to enable cros_test_lib.GerritTestCase.
GIT_PROTOCOL = 'https'

# The GOB conflict errors which could be ignorable.
GOB_CONFLICT_ERRORS = (
    r'change is closed',
    r'Cannot reduce vote on labels for closed change'
)

GOB_CONFLICT_ERRORS_RE = re.compile('|'.join(GOB_CONFLICT_ERRORS),
                                    re.IGNORECASE)

GOB_ERROR_REASON_CLOSED_CHANGE = 'CLOSED CHANGE'


class GOBError(Exception):
  """Exception class for errors commuicating with the gerrit-on-borg service."""
  def __init__(self, *args, **kwargs):
    super(GOBError, self).__init__(*args)
    self.http_status = kwargs.pop('http_status', None)
    self.reason = kwargs.pop('reason', None)

    if self.http_status is not None:
      self.message += '(http_status): %d' % self.http_status
    if self.reason is not None:
      self.message += '(reason): %s' % self.reason

class InternalGOBError(GOBError):
  """Exception class for GOB errors with status >= 500"""


def _QueryString(param_dict, first_param=None):
  """Encodes query parameters in the key:val[+key:val...] format specified here:

  https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
  """
  q = [urllib.quote(first_param)] if first_param else []
  q.extend(['%s:%s' % (key, val) for key, val in param_dict.iteritems()])
  return '+'.join(q)


def GetCookies(host, path, cookie_paths=None):
  """Returns cookies that should be set on a request.

  Used by CreateHttpConn for any requests that do not already specify a Cookie
  header. All requests made by this library are HTTPS.

  Args:
    host: The hostname of the Gerrit service.
    path: The path on the Gerrit service, already including /a/ if applicable.
    cookie_paths: Files to look in for cookies. Defaults to looking in the
      standard places where GoB places cookies.

  Returns:
    A dict of cookie name to value, with no URL encoding applied.
  """
  cookies = {}
  if cookie_paths is None:
    cookie_paths = (constants.GOB_COOKIE_PATH, constants.GITCOOKIES_PATH)
  for cookie_path in cookie_paths:
    if os.path.isfile(cookie_path):
      with open(cookie_path) as f:
        for line in f:
          fields = line.strip().split('\t')
          if line.strip().startswith('#') or len(fields) != 7:
            continue
          domain, xpath, key, value = fields[0], fields[2], fields[5], fields[6]
          if cookielib.domain_match(host, domain) and path.startswith(xpath):
            cookies[key] = value
  return cookies


def CreateHttpConn(host, path, reqtype='GET', headers=None, body=None):
  """Opens an https connection to a gerrit service, and sends a request."""
  path = '/a/' + path.lstrip('/')
  headers = headers or {}
  bare_host = host.partition(':')[0]
  auth = _NetRCAuthenticators(bare_host)
  if auth:
    headers.setdefault(
        'Authorization',
        'Basic %s' % base64.b64encode('%s:%s' % (auth[0], auth[2])))
  elif _InAppengine():
    # TODO(phobbs) how can we choose to only run this on GCE / AppEngine?
    credentials = _GetAppCredentials()
    try:
      headers.setdefault(
          'Authorization',
          'Bearer %s' % credentials.get_access_token().access_token)
    except gce.HttpAccessTokenRefreshError as e:
      logging.debug('Failed to retreive gce access token: %s', e)
    # Not in an Appengine or GCE environment.
    except httplib2.ServerNotFoundError as e:
      pass

  if not 'Authorization' in headers:
    logging.debug('No netrc file or Appengine credentials found.')
  if 'Cookie' not in headers:
    cookies = GetCookies(host, path)
    headers['Cookie'] = '; '.join('%s=%s' % (n, v) for n, v in cookies.items())

  if 'User-Agent' not in headers:
    # We may not be in a git repository.
    try:
      version = git.GetGitRepoRevision(
          os.path.dirname(os.path.realpath(__file__)))
    except cros_build_lib.RunCommandError:
      version = 'unknown'
    headers['User-Agent'] = ' '.join((
        'chromite.lib.gob_util',
        os.path.basename(sys.argv[0]),
        version,
    ))

  if body:
    body = json.JSONEncoder().encode(body)
    headers.setdefault('Content-Type', 'application/json')
  if logging.getLogger().isEnabledFor(logging.DEBUG):
    logging.debug('%s https://%s%s', reqtype, host, path)
    for key, val in headers.iteritems():
      if key.lower() in ('authorization', 'cookie'):
        val = 'HIDDEN'
      logging.debug('%s: %s', key, val)
    if body:
      logging.debug(body)
  conn = httplib.HTTPSConnection(host)
  conn.req_host = host
  conn.req_params = {
      'url': path,
      'method': reqtype,
      'headers': headers,
      'body': body,
  }
  conn.request(**conn.req_params)
  return conn


def _InAppengine():
  """Returns whether we're in the Appengine environment."""
  return _GAE_VERSION in os.environ


def FetchUrl(host, path, reqtype='GET', headers=None, body=None,
             ignore_204=False, ignore_404=True):
  """Fetches the http response from the specified URL into a string buffer.

  Args:
    host: The hostname of the Gerrit service.
    path: The path on the Gerrit service. This will be prefixed with '/a'
          automatically.
    reqtype: The request type. Can be GET or POST.
    headers: A mapping of extra HTTP headers to pass in with the request.
    body: A string of data to send after the headers are finished.
    ignore_204: for some requests gerrit-on-borg will return 204 to confirm
                proper processing of the request. When processing responses to
                these requests we should expect this status.
    ignore_404: For many requests, gerrit-on-borg will return 404 if the request
                doesn't match the database contents.  In most such cases, we
                want the API to return None rather than raise an Exception.

  Returns:
    A string buffer containing the connection's reply.
  """
  @timeout_util.TimeoutDecorator(REQUEST_TIMEOUT_SECONDS)
  def _FetchUrlHelper():
    err_prefix = 'A transient error occured while querying %s:\n' % (host,)
    try:
      conn = CreateHttpConn(host, path, reqtype=reqtype, headers=headers,
                            body=body)
      response = conn.getresponse()
    except socket.error as ex:
      logging.warning('%s%s', err_prefix, str(ex))
      raise

    # Normal/good responses.
    response_body = response.read()
    if response.status == 204 and ignore_204:
      # This exception is used to confirm expected response status.
      raise GOBError(http_status=response.status, reason=response.reason)
    if response.status == 404 and ignore_404:
      return StringIO()
    elif response.status == 200:
      return StringIO(response_body)

    # Bad responses.
    logging.debug('response msg:\n%s', response.msg)
    http_version = 'HTTP/%s' % ('1.1' if response.version == 11 else '1.0')
    ep = ErrorParser()
    ep.feed(str(response_body))
    ep.close()
    parsed_div = ep.ParsedDiv()

    msg = ('%s %s %s\n%s %d %s\nResponse body: %r' %
           (reqtype, conn.req_params['url'], http_version,
            http_version, response.status, response.reason,
            response_body))

    # Ones we can retry.
    if response.status >= 500:
      # A status >=500 is assumed to be a possible transient error; retry.
      logging.warning('%s%s', err_prefix, msg)
      raise InternalGOBError(
          http_status=response.status,
          reason=response.reason)

    # Ones we cannot retry.
    home = os.environ.get('HOME', '~')
    url = 'https://%s/new-password' % host
    if response.status in (302, 303, 307):
      err_prefix = ('Redirect found; missing/bad %s/.netrc credentials or '
                    'permissions (0600)?\n See %s' % (home, url))
    elif response.status in (400,):
      err_prefix = 'Permission error; talk to the admins of the GoB instance'
    elif response.status in (401,):
      err_prefix = ('Authorization error; missing/bad %s/.netrc credentials or '
                    'permissions (0600)?\n See %s' % (home, url))
    elif response.status in (422,):
      err_prefix = ('Bad request body?')

    logging.warning(err_prefix)

    # If GOB output contained expected error message, reduce log visibility of
    # raw GOB output reported below.
    if parsed_div:
      logging.warning('GOB Error:\n%s', parsed_div)
      logging_function = logging.debug
    else:
      logging_function = logging.warning

    logging_function(msg)
    if response.status >= 400:
      # The 'X-ErrorId' header is set only on >= 400 response code.
      logging_function('X-ErrorId: %s', response.getheader('X-ErrorId'))

    try:
      logging.warning('conn.sock.getpeername(): %s', conn.sock.getpeername())
    except AttributeError:
      logging.warning('peer name unavailable')

    if response.status == httplib.CONFLICT:
      # 409 conflict
      if GOB_CONFLICT_ERRORS_RE.search(response_body):
        raise GOBError(
            http_status=response.status,
            reason=GOB_ERROR_REASON_CLOSED_CHANGE)
      else:
        raise GOBError(http_status=response.status, reason=response.reason)
    else:
      raise GOBError(http_status=response.status, reason=response.reason)

  return retry_util.RetryException(
      (socket.error, InternalGOBError, timeout_util.TimeoutError),
      TRY_LIMIT,
      _FetchUrlHelper, sleep=SLEEP)


def FetchUrlJson(*args, **kwargs):
  """Fetch the specified URL and parse it as JSON.

  See FetchUrl for arguments.
  """
  fh = FetchUrl(*args, **kwargs)
  # The first line of the response should always be: )]}'
  s = fh.readline()
  if s and s.rstrip() != ")]}'":
    raise GOBError(http_status=200, reason='Unexpected json output: %s' % s)
  s = fh.read()
  if not s:
    return None
  return json.loads(s)


def QueryChanges(host, param_dict, first_param=None, limit=None, o_params=None,
                 start=None):
  """Queries a gerrit-on-borg server for changes matching query terms.

  Args:
    host: The Gerrit server hostname.
    param_dict: A dictionary of search parameters, as documented here:
        http://gerrit-documentation.googlecode.com/svn/Documentation/2.6/user-search.html
    first_param: A change identifier
    limit: Maximum number of results to return.
    o_params: A list of additional output specifiers, as documented here:
        https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
    start: Offset in the result set to start at.

  Returns:
    A list of json-decoded query results.
  """
  # Note that no attempt is made to escape special characters; YMMV.
  if not param_dict and not first_param:
    raise RuntimeError('QueryChanges requires search parameters')
  path = 'changes/?q=%s' % _QueryString(param_dict, first_param)
  if start:
    path = '%s&S=%d' % (path, start)
  if limit:
    path = '%s&n=%d' % (path, limit)
  if o_params:
    path = '%s&%s' % (path, '&'.join(['o=%s' % p for p in o_params]))
  # Don't ignore 404; a query should always return a list, even if it's empty.
  return FetchUrlJson(host, path, ignore_404=False)


def MultiQueryChanges(host, param_dict, change_list, limit=None, o_params=None,
                      start=None):
  """Initiate a query composed of multiple sets of query parameters."""
  if not change_list:
    raise RuntimeError(
        "MultiQueryChanges requires a list of change numbers/id's")
  q = ['q=%s' % '+OR+'.join([urllib.quote(str(x)) for x in change_list])]
  if param_dict:
    q.append(_QueryString(param_dict))
  if limit:
    q.append('n=%d' % limit)
  if start:
    q.append('S=%s' % start)
  if o_params:
    q.extend(['o=%s' % p for p in o_params])
  path = 'changes/?%s' % '&'.join(q)
  try:
    result = FetchUrlJson(host, path, ignore_404=False)
  except GOBError as e:
    msg = '%s:\n%s' % (e.message, path)
    raise GOBError(http_status=e.http_status, reason=msg)
  return result


def GetGerritFetchUrl(host):
  """Given a gerrit host name returns URL of a gerrit instance to fetch from."""
  return 'https://%s/' % host


def GetChangePageUrl(host, change_number):
  """Given a gerrit host name and change number, return change page url."""
  return 'https://%s/#/c/%d/' % (host, change_number)


def _GetChangePath(change):
  """Given a change id, return a path prefix for the change."""
  return 'changes/%s' % str(change).replace('/', '%2F')


def GetChangeUrl(host, change):
  """Given a gerrit host name and change id, return an url for the change."""
  return 'https://%s/a/%s' % (host, _GetChangePath(change))


def GetChange(host, change):
  """Query a gerrit server for information about a single change."""
  return FetchUrlJson(host, _GetChangePath(change))


def GetChangeReview(host, change, revision=None):
  """Get the current review information for a change."""
  if revision is None:
    revision = 'current'
  path = '%s/revisions/%s/review' % (_GetChangePath(change), revision)
  return FetchUrlJson(host, path)


def GetChangeCommit(host, change, revision=None):
  """Get the current review information for a change."""
  if revision is None:
    revision = 'current'
  path = '%s/revisions/%s/commit' % (_GetChangePath(change), revision)
  return FetchUrlJson(host, path)


def GetChangeCurrentRevision(host, change):
  """Get information about the latest revision for a given change."""
  jmsg = GetChangeReview(host, change)
  if jmsg:
    return jmsg.get('current_revision')


def GetChangeDetail(host, change, o_params=None):
  """Query a gerrit server for extended information about a single change."""
  path = '%s/detail' % _GetChangePath(change)
  if o_params:
    path = '%s?%s' % (path, '&'.join(['o=%s' % p for p in o_params]))
  return FetchUrlJson(host, path)


def GetChangeReviewers(host, change):
  """Get information about all reviewers attached to a change.

  Args:
    host: The Gerrit host to interact with.
    change: The Gerrit change ID.
  """
  warnings.warn('GetChangeReviewers is deprecated; use GetReviewers instead.')
  GetReviewers(host, change)


def AbandonChange(host, change, msg=''):
  """Abandon a gerrit change."""
  path = '%s/abandon' % _GetChangePath(change)
  body = {'message': msg}
  return FetchUrlJson(host, path, reqtype='POST', body=body, ignore_404=False)


def RestoreChange(host, change, msg=''):
  """Restore a previously abandoned change."""
  path = '%s/restore' % _GetChangePath(change)
  body = {'message': msg}
  return FetchUrlJson(host, path, reqtype='POST', body=body, ignore_404=False)


def DeleteDraft(host, change):
  """Delete a gerrit draft change."""
  path = _GetChangePath(change)
  try:
    FetchUrl(host, path, reqtype='DELETE', ignore_204=True, ignore_404=False)
  except GOBError as e:
    # On success, gerrit returns status 204; anything else is an error.
    if e.http_status != 204:
      raise
  else:
    raise GOBError(
        http_status=200,
        reason='Unexpectedly received a 200 http status while deleting draft '
               ' %r' % change)


def SubmitChange(host, change, revision=None, wait_for_merge=True):
  """Submits a gerrit change via Gerrit."""
  if revision is None:
    revision = 'current'
  path = '%s/revisions/%s/submit' % (_GetChangePath(change), revision)
  body = {'wait_for_merge': wait_for_merge}
  return FetchUrlJson(host, path, reqtype='POST', body=body, ignore_404=False)


def CheckChange(host, change, sha1=None):
  """Performs consistency checks on the change, and fixes inconsistencies.

  This is useful for forcing Gerrit to check whether a change has already been
  merged into the git repo. Namely, if |sha1| is provided and the change is in
  'NEW' status, Gerrit will check if a change with that |sha1| is in the repo
  and mark the change as 'MERGED' if it exists.

  Args:
    host: The Gerrit host to interact with.
    change: The Gerrit change ID.
    sha1: An optional hint of the commit's SHA1 in Git.
  """
  path = '%s/check' % (_GetChangePath(change),)
  if sha1:
    body, headers = {'expect_merged_as': sha1}, {}
  else:
    body, headers = {}, {'Content-Length': '0'}

  return FetchUrlJson(host, path, reqtype='POST',
                      body=body, ignore_404=False,
                      headers=headers)


def GetAssignee(host, change):
  """Get assignee for a change."""
  path = '%s/assignee' % _GetChangePath(change)
  return FetchUrlJson(host, path)


def AddAssignee(host, change, assignee):
  """Add reviewers to a change.

  Args:
    host: The Gerrit host to interact with.
    change: The Gerrit change ID.
    assignee: Gerrit account email as a string
  """
  path = '%s/assignee' % _GetChangePath(change)
  body = {'assignee': assignee}
  return  FetchUrlJson(host, path, reqtype='PUT', body=body, ignore_404=False)


def GetReviewers(host, change):
  """Get information about all reviewers attached to a change.

  Args:
    host: The Gerrit host to interact with.
    change: The Gerrit change ID.
  """
  path = '%s/reviewers' % _GetChangePath(change)
  return FetchUrlJson(host, path)


def AddReviewers(host, change, add=None):
  """Add reviewers to a change."""
  if not add:
    return
  if isinstance(add, basestring):
    add = (add,)
  path = '%s/reviewers' % _GetChangePath(change)
  for r in add:
    body = {'reviewer': r}
    jmsg = FetchUrlJson(host, path, reqtype='POST', body=body, ignore_404=False)
  return jmsg


def RemoveReviewers(host, change, remove=None):
  """Remove reveiewers from a change."""
  if not remove:
    return
  if isinstance(remove, basestring):
    remove = (remove,)
  for r in remove:
    path = '%s/reviewers/%s' % (_GetChangePath(change), r)
    try:
      FetchUrl(host, path, reqtype='DELETE', ignore_404=False)
    except GOBError as e:
      # On success, gerrit returns status 204; anything else is an error.
      if e.http_status != 204:
        raise
    else:
      raise GOBError(
          http_status=200,
          reason='Unexpectedly received a 200 http status while deleting'
                 ' reviewer "%s" from change %s' % (r, change))


def SetReview(host, change, revision=None, msg=None, labels=None, notify=None):
  """Set labels and/or add a message to a code review."""
  if revision is None:
    revision = 'current'
  if not msg and not labels:
    return
  path = '%s/revisions/%s/review' % (_GetChangePath(change), revision)
  body = {}
  if msg:
    body['message'] = msg
  if labels:
    body['labels'] = labels
  if notify:
    body['notify'] = notify
  response = FetchUrlJson(host, path, reqtype='POST', body=body)
  if response is None:
    raise GOBError(
        http_status=404,
        reason='CL %s not found in %s' % (change, host))
  if labels:
    for key, val in labels.iteritems():
      if ('labels' not in response or key not in response['labels'] or
          int(response['labels'][key] != int(val))):
        raise GOBError(
            http_status=200,
            reason='Unable to set "%s" label on change %s.' % (key, change))


def SetTopic(host, change, topic):
  """Set |topic| for a change. If |topic| is empty, it will be deleted"""
  path = '%s/topic' % _GetChangePath(change)
  body = {'topic': topic}
  return FetchUrlJson(host, path, reqtype='PUT', body=body, ignore_404=False)


def SetHashtags(host, change, add, remove):
  """Adds and / or removes hashtags from a change.

  Args:
    host: Hostname (without protocol prefix) of the gerrit server.
    change: A gerrit change number.
    add: a list of hashtags to be added.
    remove: a list of hashtags to be removed.
  """
  path = '%s/hashtags' % _GetChangePath(change)
  return FetchUrlJson(host, path, reqtype='POST',
                      body={'add': add, 'remove': remove},
                      ignore_404=False)


def ResetReviewLabels(host, change, label, value='0', revision=None,
                      message=None, notify=None):
  """Reset the value of a given label for all reviewers on a change."""
  if revision is None:
    revision = 'current'
  # This is tricky when working on the "current" revision, because there's
  # always the risk that the "current" revision will change in between API
  # calls.  So, the code dereferences the "current" revision down to a literal
  # sha1 at the beginning and uses it for all subsequent calls.  As a sanity
  # check, the "current" revision is dereferenced again at the end, and if it
  # differs from the previous "current" revision, an exception is raised.
  current = (revision == 'current')
  jmsg = GetChangeDetail(
      host, change, o_params=['CURRENT_REVISION', 'CURRENT_COMMIT'])
  if current:
    revision = jmsg['current_revision']
  value = str(value)
  path = '%s/revisions/%s/review' % (_GetChangePath(change), revision)
  message = message or (
      '%s label set to %s programmatically by chromite.' % (label, value))
  for review in jmsg.get('labels', {}).get(label, {}).get('all', []):
    if str(review.get('value', value)) != value:
      body = {
          'message': message,
          'labels': {label: value},
          'on_behalf_of': review['_account_id'],
      }
      if notify:
        body['notify'] = notify
      response = FetchUrlJson(host, path, reqtype='POST', body=body)
      if str(response['labels'][label]) != value:
        username = review.get('email', jmsg.get('name', ''))
        raise GOBError(
            http_status=200,
            reason='Unable to set %s label for user "%s" on change %s.' % (
                label, username, change))
  if current:
    new_revision = GetChangeCurrentRevision(host, change)
    if not new_revision:
      raise GOBError(
          http_status=200,
          reason='Could not get review information for change "%s"' % change)
    elif new_revision != revision:
      raise GOBError(
          http_status=200,
          reason='While resetting labels on change "%s", a new patchset was '
                 'uploaded.' % change)


def GetTipOfTrunkRevision(git_url):
  """Returns the current git revision on the master branch."""
  parsed_url = urlparse.urlparse(git_url)
  path = parsed_url[2].rstrip('/') + '/+log/master?n=1&format=JSON'
  j = FetchUrlJson(parsed_url[1], path, ignore_404=False)
  if not j:
    raise GOBError(
        reason='Could not find revision information from %s' % git_url)
  try:
    return j['log'][0]['commit']
  except (IndexError, KeyError, TypeError):
    msg = ('The json returned by https://%s%s has an unfamiliar structure:\n'
           '%s\n' % (parsed_url[1], path, j))
    raise GOBError(reason=msg)


def GetCommitDate(git_url, commit):
  """Returns the date of a particular git commit.

  The returned object is naive in the sense that it doesn't carry any timezone
  information - you should assume UTC.

  Args:
    git_url: URL for the repository to get the commit date from.
    commit: A git commit identifier (e.g. a sha1).

  Returns:
     A datetime object.
  """
  parsed_url = urlparse.urlparse(git_url)
  path = '%s/+log/%s?n=1&format=JSON' % (parsed_url.path.rstrip('/'), commit)
  j = FetchUrlJson(parsed_url.netloc, path, ignore_404=False)
  if not j:
    raise GOBError(
        reason='Could not find revision information from %s' % git_url)
  try:
    commit_timestr = j['log'][0]['committer']['time']
  except (IndexError, KeyError, TypeError):
    msg = ('The json returned by https://%s%s has an unfamiliar structure:\n'
           '%s\n' % (parsed_url.netloc, path, j))
    raise GOBError(reason=msg)
  try:
    # We're parsing a string of the form 'Tue Dec 02 17:48:06 2014'.
    return datetime.datetime.strptime(commit_timestr,
                                      constants.GOB_COMMIT_TIME_FORMAT)
  except ValueError:
    raise GOBError(reason='Failed parsing commit time "%s"' % commit_timestr)


def GetAccount(host):
  """Get information about the user account."""
  return FetchUrlJson(host, 'accounts/self')
