#!/usr/bin/env python
# Copyright (c) 2011 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.

"""A class to help start/stop a local apache http server."""

import logging
import optparse
import os
import subprocess
import sys
import time
import urllib

import google.path_utils
import google.platform_utils

class HttpdNotStarted(Exception): pass

def UrlIsAlive(url):
  """Checks to see if we get an http response from |url|.
  We poll the url 5 times with a 1 second delay.  If we don't
  get a reply in that time, we give up and assume the httpd
  didn't start properly.

  Args:
    url: The URL to check.
  Return:
    True if the url is alive.
  """
  wait_time = 5
  while wait_time > 0:
    try:
      response = urllib.urlopen(url)
      # Server is up and responding.
      return True
    except IOError:
      pass
    wait_time -= 1
    # Wait a second and try again.
    time.sleep(1)

  return False

def ApacheConfigDir(start_dir):
  """Returns a path to the directory holding the Apache config files."""
  return google.path_utils.FindUpward(start_dir, 'tools', 'python',
                                      'google', 'httpd_config')


def GetCygserverPath(start_dir, apache2=False):
  """Returns the path to the directory holding cygserver.exe file."""
  cygserver_path = None
  if apache2:
    cygserver_path = google.path_utils.FindUpward(start_dir, 'third_party',
                                                  'cygwin', 'usr', 'sbin')
  return cygserver_path


def StartServer(document_root=None, output_dir=None, apache2=False):
  """Starts a local server on port 8000 using the basic configuration files.

  Args:
    document_root: If present, specifies the document root for the server;
        otherwise, the filesystem's root (e.g., C:/ or /) will be used.
    output_dir: If present, specifies where to put server logs; otherwise,
        they'll be placed in the system's temp dir (e.g., $TEMP or /tmp).
    apache2: boolean if true will cause this function to configure
             for Apache 2.x as opposed to Apache 1.3.x

  Returns: the ApacheHttpd object that was created
  """
  script_dir = google.path_utils.ScriptDir()
  platform_util = google.platform_utils.PlatformUtility(script_dir)
  if not output_dir:
    output_dir = platform_util.GetTempDirectory()
  if not document_root:
    document_root = platform_util.GetFilesystemRoot()
  apache_config_dir = ApacheConfigDir(script_dir)
  if apache2:
    httpd_conf_path = os.path.join(apache_config_dir, 'httpd2.conf')
  else:
    httpd_conf_path = os.path.join(apache_config_dir, 'httpd.conf')
  mime_types_path = os.path.join(apache_config_dir, 'mime.types')
  start_cmd = platform_util.GetStartHttpdCommand(output_dir,
                                                 httpd_conf_path,
                                                 mime_types_path,
                                                 document_root,
                                                 apache2=apache2)
  stop_cmd = platform_util.GetStopHttpdCommand()
  httpd = ApacheHttpd(start_cmd, stop_cmd, [8000],
                      cygserver_path=GetCygserverPath(script_dir, apache2))
  httpd.StartServer()
  return httpd


def StopServers(apache2=False):
  """Calls the platform's stop command on a newly created server, forcing it
  to stop.

  The details depend on the behavior of the platform stop command. For example,
  it's often implemented to kill all running httpd processes, as implied by
  the name of this function.

  Args:
    apache2: boolean if true will cause this function to configure
             for Apache 2.x as opposed to Apache 1.3.x
  """
  script_dir = google.path_utils.ScriptDir()
  platform_util = google.platform_utils.PlatformUtility(script_dir)
  httpd = ApacheHttpd('', platform_util.GetStopHttpdCommand(), [],
                      cygserver_path=GetCygserverPath(script_dir, apache2))
  httpd.StopServer(force=True)


class ApacheHttpd(object):
  def __init__(self, start_command, stop_command, port_list,
               cygserver_path=None):
    """Args:
        start_command: command list to call to start the httpd
        stop_command: command list to call to stop the httpd if one has been
            started.  May kill all httpd processes running on the machine.
        port_list: list of ports expected to respond on the local machine when
            the server has been successfully started.
        cygserver_path: Path to cygserver.exe. If specified, exe will be started
            with server as well as stopped when server is stopped.
    """
    self._http_server_proc = None
    self._start_command = start_command
    self._stop_command = stop_command
    self._port_list = port_list
    self._cygserver_path = cygserver_path

  def StartServer(self):
    if self._http_server_proc:
      return
    if self._cygserver_path:
      cygserver_exe = os.path.join(self._cygserver_path, "cygserver.exe")
      cygbin = google.path_utils.FindUpward(cygserver_exe, 'third_party',
                                            'cygwin', 'bin')
      env = os.environ
      env['PATH'] += ";" + cygbin
      subprocess.Popen(cygserver_exe, env=env)
    logging.info('Starting http server')
    self._http_server_proc = subprocess.Popen(self._start_command)

    # Ensure that the server is running on all the desired ports.
    for port in self._port_list:
      if not UrlIsAlive('http://127.0.0.1:%s/' % str(port)):
        raise HttpdNotStarted('Failed to start httpd on port %s' % str(port))

  def StopServer(self, force=False):
    """If we started an httpd.exe process, or if force is True, call
    self._stop_command (passed in on init so it can be platform-dependent).
    This will presumably kill it, and may also kill any other httpd.exe
    processes that are running.
    """
    if force or self._http_server_proc:
      logging.info('Stopping http server')
      kill_proc = subprocess.Popen(self._stop_command,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
      logging.info('%s\n%s' % (kill_proc.stdout.read(),
                               kill_proc.stderr.read()))
      self._http_server_proc = None
      if self._cygserver_path:
        subprocess.Popen(["taskkill.exe", "/f", "/im", "cygserver.exe"],
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)


def main():
  # Provide some command line params for starting/stopping the http server
  # manually.
  option_parser = optparse.OptionParser()
  option_parser.add_option('-k', '--server', help='Server action (start|stop)')
  option_parser.add_option('-r', '--root', help='Document root (optional)')
  option_parser.add_option('-a', '--apache2', action='store_true',
      default=False, help='Starts Apache 2 instead of Apache 1.3 (default). '
                          'Ignored on Mac (apache2 is used always)')
  options, args = option_parser.parse_args()

  if not options.server:
    print ("Usage: %s -k {start|stop} [-r document_root] [--apache2]" %
           sys.argv[0])
    return 1

  document_root = None
  if options.root:
    document_root = options.root

  if 'start' == options.server:
    StartServer(document_root, apache2=options.apache2)
  else:
    StopServers(apache2=options.apache2)


if '__main__' == __name__:
  sys.exit(main())
