# Copyright 2011 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Platform-specific utility methods shared by several scripts."""

import os
import subprocess

import google.path_utils


class PlatformUtility(object):
  def __init__(self, base_dir):
    """Args:
         base_dir: the base dir for running tests.
    """
    self._base_dir = base_dir
    self._httpd_cmd_string = None  # used for starting/stopping httpd
    self._bash = "/bin/bash"

  def _UnixRoot(self):
    """Returns the path to root."""
    return "/"

  def GetFilesystemRoot(self):
    """Returns the root directory of the file system."""
    return self._UnixRoot()

  def GetTempDirectory(self):
    """Returns the file system temp directory

    Note that this does not use a random subdirectory, so it's not
    intrinsically secure.  If you need a secure subdir, use the tempfile
    package.
    """
    return os.getenv("TMPDIR", "/tmp")

  def FilenameToUri(self, path, use_http=False, use_ssl=False, port=8000):
    """Convert a filesystem path to a URI.

    Args:
      path: For an http URI, the path relative to the httpd server's
          DocumentRoot; for a file URI, the full path to the file.
      use_http: if True, returns a URI of the form http://127.0.0.1:8000/.
          If False, returns a file:/// URI.
      use_ssl: if True, returns HTTPS URL (https://127.0.0.1:8000/).
          This parameter is ignored if use_http=False.
      port: The port number to append when returning an HTTP URI
    """
    if use_http:
      protocol = 'http'
      if use_ssl:
        protocol = 'https'
      return "%s://127.0.0.1:%d/%s" % (protocol, port, path)
    return "file://" + path

  def GetStartHttpdCommand(self, output_dir,
                           httpd_conf_path, mime_types_path,
                           document_root=None, apache2=False):
    """Prepares the config file and output directory to start an httpd server.
    Returns a list of strings containing the server's command line+args.

    Args:
      output_dir: the path to the server's output directory, for log files.
          It will be created if necessary.
      httpd_conf_path: full path to the httpd.conf file to be used.
      mime_types_path: full path to the mime.types file to be used.
      document_root: full path to the DocumentRoot.  If None, the DocumentRoot
          from the httpd.conf file will be used.  Note that the httpd.conf
          file alongside this script does not specify any DocumentRoot, so if
          you're using that one, be sure to specify a document_root here.
      apache2: boolean if true will cause this function to return start
               command for Apache 2.x as opposed to Apache 1.3.x. This flag
               is ignored on Linux (but preserved here for compatibility in
               function signature with win), where apache2 is used always
    """

    exe_name = "apache2"
    cert_file = google.path_utils.FindUpward(self._base_dir, 'tools',
                                             'python', 'google',
                                             'httpd_config', 'httpd2.pem')
    ssl_enabled = os.path.exists('/etc/apache2/mods-enabled/ssl.conf')

    httpd_vars = {
      "httpd_executable_path":
          os.path.join(self._UnixRoot(), "usr", "sbin", exe_name),
      "httpd_conf_path": httpd_conf_path,
      "ssl_certificate_file": cert_file,
      "document_root" : document_root,
      "server_root": os.path.join(self._UnixRoot(), "usr"),
      "mime_types_path": mime_types_path,
      "output_dir": output_dir,
      "ssl_mutex": "file:"+os.path.join(output_dir, "ssl_mutex"),
      "ssl_session_cache":
          "shmcb:" + os.path.join(output_dir, "ssl_scache") + "(512000)",
      "user": os.environ.get("USER", "#%d" % os.geteuid()),
      "lock_file": os.path.join(output_dir, "accept.lock"),
    }

    google.path_utils.MaybeMakeDirectory(output_dir)

    # We have to wrap the command in bash
    # -C: process directive before reading config files
    # -c: process directive after reading config files
    # Apache wouldn't run CGIs with permissions==700 unless we add
    # -c User "<username>"
    httpd_cmd_string = (
      '%(httpd_executable_path)s'
      ' -f %(httpd_conf_path)s'
      ' -c \'TypesConfig "%(mime_types_path)s"\''
      ' -c \'CustomLog "%(output_dir)s/access_log.txt" common\''
      ' -c \'ErrorLog "%(output_dir)s/error_log.txt"\''
      ' -c \'PidFile "%(output_dir)s/httpd.pid"\''
      ' -C \'User "%(user)s"\''
      ' -C \'ServerRoot "%(server_root)s"\''
      ' -c \'LockFile "%(lock_file)s"\''
    )

    if document_root:
      httpd_cmd_string += ' -C \'DocumentRoot "%(document_root)s"\''

    if ssl_enabled:
      httpd_cmd_string += (
        ' -c \'SSLCertificateFile "%(ssl_certificate_file)s"\''
        ' -c \'SSLMutex "%(ssl_mutex)s"\''
        ' -c \'SSLSessionCache "%(ssl_session_cache)s"\''
      )

    # Save a copy of httpd_cmd_string to use for stopping httpd
    self._httpd_cmd_string = httpd_cmd_string % httpd_vars

    httpd_cmd = [self._bash, "-c", self._httpd_cmd_string]
    return httpd_cmd

  def GetStopHttpdCommand(self):
    """Returns a list of strings that contains the command line+args needed to
    stop the http server used in the http tests.

    This tries to fetch the pid of httpd (if available) and returns the
    command to kill it. If pid is not available, kill all httpd processes
    """

    if not self._httpd_cmd_string:
      return ["true"]   # Haven't been asked for the start cmd yet. Just pass.
    # Add a sleep after the shutdown because sometimes it takes some time for
    # the port to be available again.
    return [self._bash, "-c", self._httpd_cmd_string + ' -k stop && sleep 5']
