# Copyright (C) 2011 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""A class to help start/stop the lighttpd server used by layout tests."""

import logging
import os
import time

from webkitpy.common.iteration_compatibility import iteritems
from webkitpy.layout_tests.servers import http_server_base


_log = logging.getLogger(__name__)


class Lighttpd(http_server_base.HttpServerBase):

    def __init__(self, port_obj, output_dir, port=None,
                 root=None, run_background=None, additional_dirs=None,
                 layout_tests_dir=None):
        """Args:
          output_dir: the absolute path to the layout test result directory
        """
        # Webkit tests
        http_server_base.HttpServerBase.__init__(self, port_obj)
        self._name = 'lighttpd'
        self._output_dir = output_dir
        self._port = port
        self._root = root
        self._run_background = run_background
        self._additional_dirs = additional_dirs
        if layout_tests_dir:
            self.tests_dir = layout_tests_dir

        self._pid_file = self._filesystem.join(self._runtime_path, '%s.pid' % self._name)

        if self._port:
            self._port = int(self._port)

        self._webkit_tests = os.path.join(self.tests_dir, 'http', 'tests')

        # Self generated certificate for SSL server (for client cert get
        # <base-path>\chrome\test\data\ssl\certs\root_ca_cert.crt)
        self._pem_file = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'httpd2.pem')

        # One mapping where we can get to everything
        self.VIRTUALCONFIG = []

        if self._webkit_tests:
            self.VIRTUALCONFIG.extend(
               # Three mappings (one with SSL) for LayoutTests http tests
               [{'port': self.HTTP_SERVER_PORT, 'docroot': self._webkit_tests},
                {'port': self.ALTERNATIVE_HTTP_SERVER_PORT, 'docroot': self._webkit_tests},
                {'port': self.HTTPS_SERVER_PORT, 'docroot': self._webkit_tests,
                 'sslcert': self._pem_file}])

    def _prepare_config(self):
        base_conf_file = self._port_obj.path_from_webkit_base('Tools',
            'Scripts', 'webkitpy', 'layout_tests', 'servers', 'lighttpd.conf')
        out_conf_file = os.path.join(self._output_dir, 'lighttpd.conf')
        time_str = time.strftime("%d%b%Y-%H%M%S")
        access_file_name = "access.log-" + time_str + ".txt"
        access_log = os.path.join(self._output_dir, access_file_name)
        log_file_name = "error.log-" + time_str + ".txt"
        error_log = os.path.join(self._output_dir, log_file_name)

        if self._port_obj.get_option('http_access_log'):
            access_log = self._port_obj.get_option('http_access_log')

        if self._port_obj.get_option('http_error_log'):
            error_log = self._port_obj.get_option('http_error_log')

        # Write out the config
        base_conf = self._filesystem.read_text_file(base_conf_file)

        # FIXME: This should be re-worked so that this block can
        # use with open() instead of a manual file.close() call.
        f = self._filesystem.open_text_file_for_writing(out_conf_file)
        f.write(base_conf)

        # Write out our cgi handlers.  Run perl through env so that it
        # processes the #! line and runs perl with the proper command
        # line arguments. Emulate apache's mod_asis with a cat cgi handler.
        f.write('cgi.assign = ( ".cgi"  => "/usr/bin/env",\n'
                 '               ".pl"   => "/usr/bin/env",\n'
                 '               ".asis" => "/bin/cat",\n'
                 '               ".py"  => "/bin/python3" )\n\n')

        # Setup log files
        f.write(('server.errorlog = "%s"\n'
                 'accesslog.filename = "%s"\n\n') % (error_log, access_log))

        # Setup upload folders. Upload folder is to hold temporary upload files
        # and also POST data. This is used to support XHR layout tests that
        # does POST.
        f.write(('server.upload-dirs = ( "%s" )\n\n') % (self._output_dir))

        # Setup a link to where the js test templates and media resources are stored.
        operator = "="
        for alias in self.aliases():
            f.write(('alias.url %s ( "%s" => "%s" )\n\n') % (operator, alias[0], alias[1]))
            operator = "+="

        if self._additional_dirs:
            for alias, path in iteritems(self._additional_dirs):
                f.write(('alias.url += ( "%s" => "%s" )\n\n') % (alias, path))

        # dump out of virtual host config at the bottom.
        if self._root:
            if self._port:
                # Have both port and root dir.
                mappings = [{'port': self._port, 'docroot': self._root}]
            else:
                # Have only a root dir - set the ports as for LayoutTests.
                # This is used in ui_tests to run http tests against a browser.

                # default set of ports as for LayoutTests but with a
                # specified root.
                mappings = [{'port': self.HTTP_SERVER_PORT, 'docroot': self._root},
                            {'port': self.ALTERNATIVE_HTTP_SERVER_PORT, 'docroot': self._root},
                            {'port': self.HTTPS_SERVER_PORT, 'docroot': self._root,
                             'sslcert': self._pem_file}]
        else:
            mappings = self.VIRTUALCONFIG

        bind_address = '' if self._port_obj.get_option('http_all_addresses') else '127.0.0.1'
        for mapping in mappings:
            ssl_setup = ''
            if 'sslcert' in mapping:
                ssl_setup = ('  ssl.engine = "enable"\n'
                             '  ssl.pemfile = "%s"\n' % mapping['sslcert'])

            f.write(('$SERVER["socket"] == "%s:%d" {\n'
                     '  server.document-root = "%s"\n' +
                     ssl_setup +
                     '}\n\n') % (bind_address, mapping['port'], mapping['docroot']))
        f.close()

        executable = self._port_obj._path_to_lighttpd()
        module_path = self._port_obj._path_to_lighttpd_modules()
        start_cmd = [executable,
                     # Newly written config file
                     '-f', os.path.join(self._output_dir, 'lighttpd.conf'),
                     # Where it can find its module dynamic libraries
                     '-m', module_path]

        if not self._run_background:
            start_cmd.append('-D')  # Don't background.

        # Copy liblightcomp.dylib to /tmp/lighttpd/lib to work around the
        # bug that mod_alias.so loads it from the hard coded path.
        if self._port_obj.host.platform.is_mac():
            tmp_module_path = '/tmp/lighttpd/lib'
            if not self._filesystem.exists(tmp_module_path):
                self._filesystem.maybe_make_directory(tmp_module_path)
            lib_file = 'liblightcomp.dylib'
            self._filesystem.copyfile(self._filesystem.join(module_path, lib_file),
                                      self._filesystem.join(tmp_module_path, lib_file))

        self._start_cmd = start_cmd
        self._env = self._port_obj.setup_environ_for_server('lighttpd')
        self._mappings = mappings

    def _remove_stale_logs(self):
        # Sometimes logs are open in other processes but they should clear eventually.
        for log_prefix in ('access.log-', 'error.log-'):
            try:
                self._remove_log_files(self._output_dir, log_prefix)
            except OSError:
                _log.warning('Failed to remove old %s %s files' % (self._name, log_prefix))

    def _spawn_process(self):
        _log.debug('Starting %s server, cmd="%s"' % (self._name, self._start_cmd))
        self._process = self._executive.popen(self._start_cmd, env=self._env, shell=False, stderr=self._executive.PIPE)
        pid = self._process.pid
        self._filesystem.write_text_file(self._pid_file, str(pid))
        return pid

    def _stop_running_server(self):
        # FIXME: It would be nice if we had a cleaner way of killing this process.
        # Currently we throw away the process object created in _spawn_process,
        # since there doesn't appear to be any way to kill the server any more
        # cleanly using it than just killing the pid, and we need to support
        # killing a pid directly anyway for run-webkit-httpd and run-webkit-websocketserver.
        self._wait_for_action(self._check_and_kill)
        if self._filesystem.exists(self._pid_file):
            self._filesystem.remove(self._pid_file)

    def _check_and_kill(self):
        if self._process is not None:
            self._process.poll()
            if self._process.returncode is not None:
                return True

        if self._executive.check_running_pid(self._pid):
            host = self._port_obj.host
            if host.platform.is_win() and not host.platform.is_cygwin():
                # FIXME: https://bugs.webkit.org/show_bug.cgi?id=106838
                # We need to kill all of the child processes as well as the
                # parent, so we can't use executive.kill_process().
                #
                # If this is actually working, we should figure out a clean API.
                self._executive.run_command(["taskkill.exe", "/f", "/t", "/pid", self._pid], ignore_errors=True)
            else:
                self._executive.kill_process(self._pid)
            return False
        return True

    def _is_server_running_on_all_ports(self):
        if self._process is not None:
            self._process.poll()
            if self._process.returncode is not None:
                _log.debug("Server isn't running at all")
                raise http_server_base.ServerError("Server exited")

        return super(Lighttpd, self)._is_server_running_on_all_ports()
