#!/usr/bin/env python
# Copyright 2012 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.

"""Retrieve web resources over http."""

import copy
import datetime
import httplib
import logging
import random
import ssl
import StringIO

import httparchive
import platformsettings
import script_injector


# PIL isn't always available, but we still want to be able to run without
# the image scrambling functionality in this case.
try:
  import Image
except ImportError:
  Image = None

TIMER = platformsettings.timer


class HttpClientException(Exception):
  """Base class for all exceptions in httpclient."""
  pass


def _InjectScripts(response, injector):
  """Injects script generated by |injector| immediately after <head> or <html>.

  Copies |response| if it is modified.

  Args:
    response: an ArchivedHttpResponse
    injector: function which generates JavaScript string
      based on recording time (e.g. "Math.random = function(){...}")
  Returns:
    an ArchivedHttpResponse
  """
  if type(response) == tuple:
    logging.warn('tuple response: %s', response)
  content_type = response.get_header('content-type')
  if content_type and content_type.startswith('text/html'):
    text_chunks = response.get_data_as_chunks()
    text_chunks, just_injected = script_injector.InjectScript(
        text_chunks, 'text/html', injector(response.request_time))
    if just_injected:
      response = copy.deepcopy(response)
      response.set_data_from_chunks(text_chunks)
  return response


def _ScrambleImages(response):
  """If the |response| is an image, attempt to scramble it.

  Copies |response| if it is modified.

  Args:
    response: an ArchivedHttpResponse
  Returns:
    an ArchivedHttpResponse
  """

  assert Image, '--scramble_images requires the PIL module to be installed.'

  content_type = response.get_header('content-type')
  if content_type and content_type.startswith('image/'):
    try:
      image_data = response.response_data[0]
      image_data.decode(encoding='base64')
      im = Image.open(StringIO.StringIO(image_data))

      pixel_data = list(im.getdata())
      random.shuffle(pixel_data)

      scrambled_image = im.copy()
      scrambled_image.putdata(pixel_data)

      output_image_io = StringIO.StringIO()
      scrambled_image.save(output_image_io, im.format)
      output_image_data = output_image_io.getvalue()
      output_image_data.encode(encoding='base64')

      response = copy.deepcopy(response)
      response.set_data(output_image_data)
    except Exception:
      pass

  return response


class DetailedHTTPResponse(httplib.HTTPResponse):
  """Preserve details relevant to replaying responses.

  WARNING: This code uses attributes and methods of HTTPResponse
  that are not part of the public interface.
  """

  def read_chunks(self):
    """Return the response body content and timing data.

    The returned chunks have the chunk size and CRLFs stripped off.
    If the response was compressed, the returned data is still compressed.

    Returns:
      (chunks, delays)
        chunks:
          [response_body]                  # non-chunked responses
          [chunk_1, chunk_2, ...]          # chunked responses
        delays:
          [0]                              # non-chunked responses
          [chunk_1_first_byte_delay, ...]  # chunked responses

      The delay for the first body item should be recorded by the caller.
    """
    buf = []
    chunks = []
    delays = []
    if not self.chunked:
      chunks.append(self.read())
      delays.append(0)
    else:
      start = TIMER()
      try:
        while True:
          line = self.fp.readline()
          chunk_size = self._read_chunk_size(line)
          if chunk_size is None:
            raise httplib.IncompleteRead(''.join(chunks))
          if chunk_size == 0:
            break
          delays.append(TIMER() - start)
          chunks.append(self._safe_read(chunk_size))
          self._safe_read(2)  # skip the CRLF at the end of the chunk
          start = TIMER()

        # Ignore any trailers.
        while True:
          line = self.fp.readline()
          if not line or line == '\r\n':
            break
      finally:
        self.close()
    return chunks, delays

  @classmethod
  def _read_chunk_size(cls, line):
    chunk_extensions_pos = line.find(';')
    if chunk_extensions_pos != -1:
      line = line[:chunk_extensions_pos]  # strip chunk-extensions
    try:
      chunk_size = int(line, 16)
    except ValueError:
      return None
    return chunk_size


class DetailedHTTPConnection(httplib.HTTPConnection):
  """Preserve details relevant to replaying connections."""
  response_class = DetailedHTTPResponse


class DetailedHTTPSResponse(DetailedHTTPResponse):
  """Preserve details relevant to replaying SSL responses."""
  pass


class DetailedHTTPSConnection(httplib.HTTPSConnection):
  """Preserve details relevant to replaying SSL connections."""
  response_class = DetailedHTTPSResponse

  def __init__(self, host, port):
    # https://www.python.org/dev/peps/pep-0476/#opting-out
    if hasattr(ssl, '_create_unverified_context'):
      httplib.HTTPSConnection.__init__(
          self, host=host, port=port, context=ssl._create_unverified_context())
    else:
      httplib.HTTPSConnection.__init__(self, host=host, port=port)


class RealHttpFetch(object):

  def __init__(self, real_dns_lookup):
    """Initialize RealHttpFetch.

    Args:
      real_dns_lookup: a function that resolves a host to an IP. RealHttpFetch
        will resolve host name to the IP before making fetching request if this
        is not None.
    """
    self._real_dns_lookup = real_dns_lookup

  @staticmethod
  def _GetHeaderNameValue(header):
    """Parse the header line and return a name/value tuple.

    Args:
      header: a string for a header such as "Content-Length: 314".
    Returns:
      A tuple (header_name, header_value) on success or None if the header
      is not in expected format. header_name is in lowercase.
    """
    i = header.find(':')
    if i > 0:
      return (header[:i].lower(), header[i+1:].strip())
    return None

  @staticmethod
  def _ToTuples(headers):
    """Parse headers and save them to a list of tuples.

    This method takes HttpResponse.msg.headers as input and convert it
    to a list of (header_name, header_value) tuples.
    HttpResponse.msg.headers is a list of strings where each string
    represents either a header or a continuation line of a header.
    1. a normal header consists of two parts which are separated by colon :
       "header_name:header_value..."
    2. a continuation line is a string starting with whitespace
       "[whitespace]continued_header_value..."
    If a header is not in good shape or an unexpected continuation line is
    seen, it will be ignored.

    Should avoid using response.getheaders() directly
    because response.getheaders() can't handle multiple headers
    with the same name properly. Instead, parse the
    response.msg.headers using this method to get all headers.

    Args:
      headers: an instance of HttpResponse.msg.headers.
    Returns:
      A list of tuples which looks like:
      [(header_name, header_value), (header_name2, header_value2)...]
    """
    all_headers = []
    for line in headers:
      if line[0] in '\t ':
        if not all_headers:
          logging.warning(
              'Unexpected response header continuation line [%s]', line)
          continue
        name, value = all_headers.pop()
        value += '\n ' + line.strip()
      else:
        name_value = RealHttpFetch._GetHeaderNameValue(line)
        if not name_value:
          logging.warning(
              'Response header in wrong format [%s]', line)
          continue
        name, value = name_value  # pylint: disable=unpacking-non-sequence
      all_headers.append((name, value))
    return all_headers

  @staticmethod
  def _get_request_host_port(request):
    host_parts = request.host.split(':')
    host = host_parts[0]
    port = int(host_parts[1]) if len(host_parts) == 2 else None
    return host, port

  @staticmethod
  def _get_system_proxy(is_ssl):
    return platformsettings.get_system_proxy(is_ssl)

  def _get_connection(self, request_host, request_port, is_ssl):
    """Return a detailed connection object for host/port pair.

    If a system proxy is defined (see platformsettings.py), it will be used.

    Args:
      request_host: a host string (e.g. "www.example.com").
      request_port: a port integer (e.g. 8080) or None (for the default port).
      is_ssl: True if HTTPS connection is needed.
    Returns:
      A DetailedHTTPSConnection or DetailedHTTPConnection instance.
    """
    connection_host = request_host
    connection_port = request_port
    system_proxy = self._get_system_proxy(is_ssl)
    if system_proxy:
      connection_host = system_proxy.host
      connection_port = system_proxy.port

    # Use an IP address because WPR may override DNS settings.
    if self._real_dns_lookup:
      connection_ip = self._real_dns_lookup(connection_host)
      if not connection_ip:
        logging.critical(
            'Unable to find IP for host name: %s', connection_host)
        return None
      connection_host = connection_ip

    if is_ssl:
      connection = DetailedHTTPSConnection(connection_host, connection_port)
      if system_proxy:
        connection.set_tunnel(request_host, request_port)
    else:
      connection = DetailedHTTPConnection(connection_host, connection_port)
    return connection

  def __call__(self, request):
    """Fetch an HTTP request.

    Args:
      request: an ArchivedHttpRequest
    Returns:
      an ArchivedHttpResponse
    """
    logging.debug('RealHttpFetch: %s %s', request.host, request.full_path)
    request_host, request_port = self._get_request_host_port(request)
    retries = 3
    while True:
      try:
        request_time = datetime.datetime.utcnow()
        connection = self._get_connection(
            request_host, request_port, request.is_ssl)
        connect_start = TIMER()
        connection.connect()
        connect_delay = int((TIMER() - connect_start) * 1000)
        start = TIMER()
        connection.request(
            request.command,
            request.full_path,
            request.request_body,
            request.headers)
        response = connection.getresponse()
        headers_delay = int((TIMER() - start) * 1000)

        chunks, chunk_delays = response.read_chunks()
        delays = {
            'connect': connect_delay,
            'headers': headers_delay,
            'data': chunk_delays
            }
        archived_http_response = httparchive.ArchivedHttpResponse(
            response.version,
            response.status,
            response.reason,
            RealHttpFetch._ToTuples(response.msg.headers),
            chunks,
            delays,
            request_time)
        return archived_http_response
      except Exception, e:
        if retries:
          retries -= 1
          logging.warning('Retrying fetch %s: %s', request, repr(e))
          continue
        logging.critical('Could not fetch %s: %s', request, repr(e))
        return None


class RecordHttpArchiveFetch(object):
  """Make real HTTP fetches and save responses in the given HttpArchive."""

  def __init__(self, http_archive, injector):
    """Initialize RecordHttpArchiveFetch.

    Args:
      http_archive: an instance of a HttpArchive
      injector: script injector to inject scripts in all pages
    """
    self.http_archive = http_archive
    # Do not resolve host name to IP when recording to avoid SSL3 handshake
    # failure.
    # See https://github.com/chromium/web-page-replay/issues/73 for details.
    self.real_http_fetch = RealHttpFetch(real_dns_lookup=None)
    self.injector = injector

  def __call__(self, request):
    """Fetch the request and return the response.

    Args:
      request: an ArchivedHttpRequest.
    Returns:
      an ArchivedHttpResponse
    """
    # If request is already in the archive, return the archived response.
    if request in self.http_archive:
      logging.debug('Repeated request found: %s', request)
      response = self.http_archive[request]
    else:
      response = self.real_http_fetch(request)
      if response is None:
        return None
      self.http_archive[request] = response
    if self.injector:
      response = _InjectScripts(response, self.injector)
    logging.debug('Recorded: %s', request)
    return response


class ReplayHttpArchiveFetch(object):
  """Serve responses from the given HttpArchive."""

  def __init__(self, http_archive, real_dns_lookup, injector,
               use_diff_on_unknown_requests=False,
               use_closest_match=False, scramble_images=False):
    """Initialize ReplayHttpArchiveFetch.

    Args:
      http_archive: an instance of a HttpArchive
      real_dns_lookup: a function that resolves a host to an IP.
      injector: script injector to inject scripts in all pages
      use_diff_on_unknown_requests: If True, log unknown requests
        with a diff to requests that look similar.
      use_closest_match: If True, on replay mode, serve the closest match
        in the archive instead of giving a 404.
    """
    self.http_archive = http_archive
    self.injector = injector
    self.use_diff_on_unknown_requests = use_diff_on_unknown_requests
    self.use_closest_match = use_closest_match
    self.scramble_images = scramble_images
    self.real_http_fetch = RealHttpFetch(real_dns_lookup)

  def __call__(self, request):
    """Fetch the request and return the response.

    Args:
      request: an instance of an ArchivedHttpRequest.
    Returns:
      Instance of ArchivedHttpResponse (if found) or None
    """
    if request.host.startswith('127.0.0.1:'):
      return self.real_http_fetch(request)

    response = self.http_archive.get(request)

    if self.use_closest_match and not response:
      closest_request = self.http_archive.find_closest_request(
          request, use_path=True)
      if closest_request:
        response = self.http_archive.get(closest_request)
        if response:
          logging.info('Request not found: %s\nUsing closest match: %s',
                       request, closest_request)

    if not response:
      reason = str(request)
      if self.use_diff_on_unknown_requests:
        diff = self.http_archive.diff(request)
        if diff:
          reason += (
              "\nNearest request diff "
              "('-' for archived request, '+' for current request):\n%s" % diff)
      logging.warning('Could not replay: %s', reason)
    else:
      if self.injector:
        response = _InjectScripts(response, self.injector)
      if self.scramble_images:
        response = _ScrambleImages(response)
    return response


class ControllableHttpArchiveFetch(object):
  """Controllable fetch function that can swap between record and replay."""

  def __init__(self, http_archive, real_dns_lookup,
               injector, use_diff_on_unknown_requests,
               use_record_mode, use_closest_match, scramble_images):
    """Initialize HttpArchiveFetch.

    Args:
      http_archive: an instance of a HttpArchive
      real_dns_lookup: a function that resolves a host to an IP.
      injector: function to inject scripts in all pages.
        takes recording time as datetime.datetime object.
      use_diff_on_unknown_requests: If True, log unknown requests
        with a diff to requests that look similar.
      use_record_mode: If True, start in server in record mode.
      use_closest_match: If True, on replay mode, serve the closest match
        in the archive instead of giving a 404.
    """
    self.http_archive = http_archive
    self.record_fetch = RecordHttpArchiveFetch(http_archive, injector)
    self.replay_fetch = ReplayHttpArchiveFetch(
        http_archive, real_dns_lookup, injector,
        use_diff_on_unknown_requests, use_closest_match, scramble_images)
    if use_record_mode:
      self.SetRecordMode()
    else:
      self.SetReplayMode()

  def SetRecordMode(self):
    self.fetch = self.record_fetch
    self.is_record_mode = True

  def SetReplayMode(self):
    self.fetch = self.replay_fetch
    self.is_record_mode = False

  def __call__(self, *args, **kwargs):
    """Forward calls to Replay/Record fetch functions depending on mode."""
    return self.fetch(*args, **kwargs)
