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

"""Start and stop the Apache HTTP server as it is used by the web tests."""

import logging
import socket

from blinkpy.web_tests.servers import server_base


_log = logging.getLogger(__name__)


class ApacheHTTP(server_base.ServerBase):

    def __init__(self, port_obj, output_dir, additional_dirs, number_of_servers):
        super(ApacheHTTP, self).__init__(port_obj, output_dir)
        # We use the name "httpd" instead of "apache" to make our paths (e.g. the pid file: /tmp/WebKit/httpd.pid)
        # match old-run-webkit-tests: https://bugs.webkit.org/show_bug.cgi?id=63956
        self._name = 'httpd'
        self._log_prefixes = ('access_log', 'error_log')
        self._mappings = [{'port': 8000},
                          {'port': 8080},
                          {'port': 8443, 'sslcert': True}]
        self._number_of_servers = number_of_servers

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

        executable = self._port_obj.path_to_apache()
        server_root = self._filesystem.dirname(self._filesystem.dirname(executable))

        test_dir = self._port_obj.web_tests_dir()
        document_root = self._filesystem.join(test_dir, 'http', 'tests')
        forms_test_resources_dir = self._filesystem.join(test_dir, 'fast', 'forms', 'resources')
        media_resources_dir = self._filesystem.join(test_dir, 'media')
        webaudio_resources_dir = self._filesystem.join(test_dir, 'webaudio', 'resources')
        mime_types_path = self._filesystem.join(self._port_obj.apache_config_directory(), 'mime.types')
        cert_file = self._filesystem.join(self._port_obj.apache_config_directory(), 'webkit-httpd.pem')
        inspector_sources_dir = self._port_obj.inspector_build_directory()
        generated_sources_dir = self._port_obj.generated_sources_directory()
        php_ini_dir = self._filesystem.join(test_dir, "http", "conf")

        self._access_log_path = self._filesystem.join(output_dir, 'access_log.txt')
        self._error_log_path = self._filesystem.join(output_dir, 'error_log.txt')

        self._is_win = self._port_obj.host.platform.is_win()

        start_cmd = [
            executable,
            '-f', '%s' % self._port_obj.path_to_apache_config_file(),
            '-C', 'ServerRoot "%s"' % server_root,
            '-C', 'DocumentRoot "%s"' % document_root,
            '-c', 'Alias /js-test-resources "%s/resources"' % test_dir,
            '-c', 'Alias /geolocation-api/js-test-resources "%s/geolocation-api/resources"' % test_dir,
            # TODO(509038): To be removed after bluetooth tests are ported to WPT.
            '-c', 'Alias /resources/chromium "%s/external/wpt/resources/chromium"' % test_dir,
            '-c', 'Alias /resources/testharness.js "%s/resources/testharness.js"' % test_dir,
            '-c', 'Alias /resources/testharnessreport.js "%s/resources/testharnessreport.js"' % test_dir,
            '-c', 'Alias /w3c/resources "%s/resources"' % test_dir,
            # TODO(509038): To be removed after bluetooth tests are ported to WPT.
            '-c', 'Alias /bluetooth-resources "%s/external/wpt/bluetooth/resources"' % test_dir,
            '-c', 'Alias /forms-test-resources "%s"' % forms_test_resources_dir,
            '-c', 'Alias /media-resources "%s"' % media_resources_dir,
            '-c', 'Alias /webaudio-resources "%s"' % webaudio_resources_dir,
            '-c', 'Alias /inspector-sources "%s"' % inspector_sources_dir,
            '-c', 'Alias /gen "%s"' % generated_sources_dir,
            '-c', 'TypesConfig "%s"' % mime_types_path,
            '-c', 'CustomLog "%s" common' % self._access_log_path,
            '-c', 'ErrorLog "%s"' % self._error_log_path,
            '-c', 'PHPINIDir "%s"' % php_ini_dir,
            '-c', 'PidFile %s' % self._pid_file,
            '-c', 'SSLCertificateFile "%s"' % cert_file,
            '-c', 'DefaultType None',
        ]

        if self._is_win:
            start_cmd += ['-c', 'ThreadsPerChild %d' % (self._number_of_servers * 8)]
        else:
            start_cmd += ['-c', 'StartServers %d' % self._number_of_servers,
                          '-c', 'MinSpareServers %d' % self._number_of_servers,
                          '-c', 'MaxSpareServers %d' % self._number_of_servers,
                          '-C', 'User "%s"' % self._port_obj.host.environ.get('USERNAME',
                                                                              self._port_obj.host.environ.get('USER', '')),
                          '-k', 'start']

        if self._port_obj.http_server_requires_http_protocol_options_unsafe():
            start_cmd += ['-c', 'HttpProtocolOptions Unsafe']

        enable_ipv6 = self._port_obj.http_server_supports_ipv6()
        # Perform part of the checks Apache's APR does when trying to listen to
        # a specific host/port. This allows us to avoid trying to listen to
        # IPV6 addresses when it fails on Apache. APR itself tries to call
        # getaddrinfo() again without AI_ADDRCONFIG if the first call fails
        # with EBADFLAGS, but that is not how it normally fails in our use
        # cases, so ignore that for now.
        # See https://bugs.webkit.org/show_bug.cgi?id=98602#c7
        try:
            socket.getaddrinfo('::1', 0, 0, 0, 0, socket.AI_ADDRCONFIG)
        except:
            enable_ipv6 = False

        for mapping in self._mappings:
            port = mapping['port']

            start_cmd += ['-C', 'Listen 127.0.0.1:%d' % port]

            # We listen to both IPv4 and IPv6 loop-back addresses, but ignore
            # requests to 8000 from random users on network.
            # See https://bugs.webkit.org/show_bug.cgi?id=37104
            if enable_ipv6:
                start_cmd += ['-C', 'Listen [::1]:%d' % port]

        if additional_dirs:
            self._start_cmd = start_cmd
            for alias, path in additional_dirs.iteritems():
                start_cmd += ['-c', 'Alias %s "%s"' % (alias, path),
                              # Disable CGI handler for additional dirs.
                              '-c', '<Location %s>' % alias,
                              '-c', 'RemoveHandler .cgi .pl',
                              '-c', '</Location>']

        self._start_cmd = start_cmd

    def _spawn_process(self):
        _log.debug('Starting %s server, cmd="%s"', self._name, str(self._start_cmd))
        self._process = self._executive.popen(self._start_cmd)
        retval = self._process.returncode
        if retval:
            raise server_base.ServerError('Failed to start %s: %s' % (self._name, retval))

        # For some reason apache isn't guaranteed to have created the pid file before
        # the process exits, so we wait a little while longer.
        if not self._wait_for_action(lambda: self._filesystem.exists(self._pid_file)):
            self._log_errors_from_subprocess()
            raise server_base.ServerError('Failed to start %s: no pid file found' % self._name)

        return int(self._filesystem.read_text_file(self._pid_file))

    def stop(self):
        self._stop_running_server()

    def _stop_running_server(self):
        # If apache was forcefully killed, the pid file will not have been deleted, so check
        # that the process specified by the pid_file no longer exists before deleting the file.
        if self._pid and not self._executive.check_running_pid(self._pid):
            self._filesystem.remove(self._pid_file)
            return

        if self._is_win:
            self._executive.kill_process(self._pid)
            return

        proc = self._executive.popen([self._port_obj.path_to_apache(),
                                      '-f', self._port_obj.path_to_apache_config_file(),
                                      '-c', 'PidFile "%s"' % self._pid_file,
                                      '-k', 'stop'])
        _, err = proc.communicate()
        retval = proc.returncode
        if retval or (err and len(err)):
            raise server_base.ServerError('Failed to stop %s: %s %s' % (self._name, err))

        # For some reason apache isn't guaranteed to have actually stopped after
        # the stop command returns, so we wait a little while longer for the
        # pid file to be removed.
        if not self._wait_for_action(lambda: not self._filesystem.exists(self._pid_file)):
            raise server_base.ServerError('Failed to stop %s: pid file still exists' % self._name)
