# 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)
      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
