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

import atexit
import datetime
import email.utils
import errno
import hashlib
import logging
import math
import os.path
import socket
import subprocess
import tempfile
import threading

import SimpleHTTPServer
import SocketServer

_ZERO = datetime.timedelta(0)


class UTC_TZINFO(datetime.tzinfo):
  """UTC time zone representation."""

  def utcoffset(self, _):
    return _ZERO

  def tzname(self, _):
    return "UTC"

  def dst(self, _):
     return _ZERO

_UTC = UTC_TZINFO()


def _gzip(file_path):
  """Gzips the given file storing the result in a temporary file.

  Returns:
    Path to the resulting file.
  """
  gzipped_file = tempfile.NamedTemporaryFile(delete=False)
  try:
    subprocess.check_call(['gzip', '-c', file_path],
                          stdout=gzipped_file)
  except Exception:
    print ('http_server: call to gzip failed, make sure that '
           'gzip is installed on the host.')
    raise
  gzipped_file.close()
  return gzipped_file.name


class _SilentTCPServer(SocketServer.TCPServer):
  """A TCPServer that won't display any error, unless debugging is enabled. This
  is useful because the client might stop while it is fetching an URL, which
  causes spurious error messages.
  """
  allow_reuse_address = True

  def handle_error(self, request, client_address):
    """Override the base class method to have conditional logging."""
    if logging.getLogger().isEnabledFor(logging.DEBUG):
      SocketServer.TCPServer.handle_error(self, request, client_address)


def _get_handler_class_for_path(mappings):
  """Creates a handler override for SimpleHTTPServer.

  Args:
    mappings: List of tuples (prefix, local_base_path_list) mapping URLs that
        start with |prefix| to one or more local directories enumerated in
        |local_base_path_list|. The prefixes should skip the leading slash.
        The first matching prefix and the first location that contains the
        requested file will be used each time.
  """
  for prefix, _ in mappings:
    assert not prefix.startswith('/'), ('Prefixes for the http server mappings '
                                        'should skip the leading slash.')

  class RequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    """Handler for SocketServer.TCPServer that will serve the files from
    local directiories over http.

    A new instance is created for each request.
    """

    def __init__(self, *args, **kwargs):
      self.etag = None
      self.gzipped_file_name = None
      self.original_file_name = None
      SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, *args, **kwargs)

    def get_etag(self):
      if self.etag:
        return self.etag

      path = self.translate_path(self.path, False)
      if not os.path.isfile(path):
        return None

      sha256 = hashlib.sha256()
      BLOCKSIZE = 65536
      with open(path, 'rb') as hashed:
        buf = hashed.read(BLOCKSIZE)
        while len(buf) > 0:
          sha256.update(buf)
          buf = hashed.read(BLOCKSIZE)
      self.etag = '"%s"' % sha256.hexdigest()
      return self.etag

    def send_head(self):
      # Always close the connection after each request, as the keep alive
      # support from SimpleHTTPServer doesn't like when the client requests to
      # close the connection before downloading the full response content.
      # pylint: disable=W0201
      self.close_connection = 1

      path = self.translate_path(self.path, False)
      if os.path.isfile(path):
        # Handle If-None-Match
        etag = self.get_etag()
        if ('If-None-Match' in self.headers and
            etag == self.headers['If-None-Match']):
          self.send_response(304)
          return None

        # Handle If-Modified-Since
        if ('If-None-Match' not in self.headers and
            'If-Modified-Since' in self.headers):
          last_modified = datetime.datetime.fromtimestamp(
              math.floor(os.stat(path).st_mtime), tz=_UTC)
          ims = datetime.datetime(
              *email.utils.parsedate(self.headers['If-Modified-Since'])[:6],
              tzinfo=_UTC)
          if last_modified <= ims:
            self.send_response(304)
            return None

      return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)

    def end_headers(self):
      path = self.translate_path(self.path)

      if os.path.isfile(path):
        self.send_header('Content-Encoding', 'gzip')
        etag = self.get_etag()
        if etag:
          self.send_header('ETag', etag)
          self.send_header('Cache-Control', 'must-revalidate')

      return SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)

    # pylint: disable=W0221
    def translate_path(self, path, gzip=True):
      # Parent translate_path() will strip away the query string and fragment
      # identifier, but also will prepend the cwd to the path. relpath() gives
      # us the relative path back.
      normalized_path = os.path.relpath(
          SimpleHTTPServer.SimpleHTTPRequestHandler.translate_path(self, path))

      for prefix, local_base_path_list in mappings:
        if not normalized_path.startswith(prefix):
          continue

        for local_base_path in local_base_path_list:
          candidate = os.path.join(local_base_path,
                                   normalized_path[len(prefix):])
          if os.path.isfile(candidate):
            if gzip:
              if not self.gzipped_file_name:
                self.original_file_name = candidate
                self.gzipped_file_name = _gzip(candidate)
              return self.gzipped_file_name
            return candidate
        else:
          self.send_response(404)
          return None
      self.send_response(404)
      return None

    def guess_type(self, path):
      # This is needed so that exploded Sky apps without shebang can still run
      # thanks to content-type mappings.
      # TODO(ppi): drop this part once we can rely on the Sky files declaring
      # correct shebang.
      actual_path = self.original_file_name or path

      if actual_path.endswith('.dart'):
        return 'application/dart'
      return SimpleHTTPServer.SimpleHTTPRequestHandler.guess_type(self,
                                                                  actual_path)

    def log_message(self, *_):
      """Override the base class method to disable logging."""
      pass

    def __del__(self):
      if self.gzipped_file_name:
        os.remove(self.gzipped_file_name)

  RequestHandler.protocol_version = 'HTTP/1.1'
  return RequestHandler


def start_http_server(mappings, host_port=0):
  """Starts an http server serving files from |local_dir_path| on |host_port|.

  Args:
    mappings: List of tuples (prefix, local_base_path_list) mapping URLs that
        start with |prefix| to one or more local directories enumerated in
        |local_base_path_list|. The prefixes should skip the leading slash.
        The first matching prefix and the first location that contains the
        requested file will be used each time.
    host_port: Port on the host machine to run the server on. Pass 0 to use a
        system-assigned port.

  Returns:
    Tuple of the server address and the port on which it runs.
  """
  assert mappings
  handler_class = _get_handler_class_for_path(mappings)

  try:
    httpd = _SilentTCPServer(('127.0.0.1', host_port), handler_class)
    atexit.register(httpd.shutdown)

    http_thread = threading.Thread(target=httpd.serve_forever)
    http_thread.daemon = True
    http_thread.start()
    return httpd.server_address
  except socket.error as v:
    error_code = v[0]
    print 'Failed to start http server for %s on port %d: %s.' % (
        str(mappings), host_port, os.strerror(error_code))
    if error_code == errno.EADDRINUSE:
      print ('  Run `fuser %d/tcp` to find out which process is using the port;'
             % host_port)
      print ('  or `fuser -k %d/tcp` terminate it.' % host_port)
    print '---'
    raise
