#!/usr/bin/env python
# Copyright (C) 2010 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."""

from __future__ import with_statement

import codecs
import logging
import optparse
import os
import shutil
import subprocess
import sys
import tempfile
import time
import urllib

import factory
import http_server_base

_log = logging.getLogger("webkitpy.layout_tests.port.http_server")


class HttpdNotStarted(Exception):
    pass


class Lighttpd(http_server_base.HttpServerBase):

    def __init__(self, port_obj, output_dir, background=False, port=None,
                 root=None, run_background=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._output_dir = output_dir
        self._process = None
        self._port = port
        self._root = root
        self._run_background = run_background
        self._layout_tests_dir = layout_tests_dir

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

        if not self._layout_tests_dir:
            self._layout_tests_dir = self._port_obj.layout_tests_dir()

        try:
            self._webkit_tests = os.path.join(
                self._layout_tests_dir, 'http', 'tests')
            self._js_test_resource = os.path.join(
                self._layout_tests_dir, 'fast', 'js', 'resources')
            self._media_resource = os.path.join(
                self._layout_tests_dir, 'media')

        except:
            self._webkit_tests = None
            self._js_test_resource = None
            self._media_resource = None

        # 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': 8000, 'docroot': self._webkit_tests},
                {'port': 8080, 'docroot': self._webkit_tests},
                {'port': 8443, 'docroot': self._webkit_tests,
                 'sslcert': self._pem_file}])

    def is_running(self):
        return self._process != None

    def start(self):
        if self.is_running():
            raise 'Lighttpd already running'

        base_conf_file = self._port_obj.path_from_webkit_base('Tools',
            'Scripts', 'webkitpy', 'layout_tests', 'port', '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)

        # Remove old log files. We only need to keep the last ones.
        self.remove_log_files(self._output_dir, "access.log-")
        self.remove_log_files(self._output_dir, "error.log-")

        # Write out the config
        with codecs.open(base_conf_file, "r", "utf-8") as file:
            base_conf = file.read()

        # FIXME: This should be re-worked so that this block can
        # use with open() instead of a manual file.close() call.
        # lighttpd.conf files seem to be UTF-8 without BOM:
        # http://redmine.lighttpd.net/issues/992
        f = codecs.open(out_conf_file, "w", "utf-8")
        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'
                 '               ".php"  => "%s" )\n\n') %
                                     self._port_obj._path_to_lighttpd_php())

        # 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 are stored
        f.write(('alias.url = ( "/js-test-resources" => "%s" )\n\n') %
                    (self._js_test_resource))

        # Setup a link to where the media resources are stored.
        f.write(('alias.url += ( "/media-resources" => "%s" )\n\n') %
                    (self._media_resource))

        # 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': 8000, 'docroot': self._root},
                            {'port': 8080, 'docroot': self._root},
                            {'port': 8443, 'docroot': self._root,
                             'sslcert': self._pem_file}]
        else:
            mappings = self.VIRTUALCONFIG
        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"] == "127.0.0.1:%d" {\n'
                     '  server.document-root = "%s"\n' +
                     ssl_setup +
                     '}\n\n') % (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(# Don't background
                             '-D')

        # Copy liblightcomp.dylib to /tmp/lighttpd/lib to work around the
        # bug that mod_alias.so loads it from the hard coded path.
        if sys.platform == 'darwin':
            tmp_module_path = '/tmp/lighttpd/lib'
            if not os.path.exists(tmp_module_path):
                os.makedirs(tmp_module_path)
            lib_file = 'liblightcomp.dylib'
            shutil.copyfile(os.path.join(module_path, lib_file),
                            os.path.join(tmp_module_path, lib_file))

        env = self._port_obj.setup_environ_for_server()
        _log.debug('Starting http server, cmd="%s"' % str(start_cmd))
        # FIXME: Should use Executive.run_command
        self._process = subprocess.Popen(start_cmd, env=env, stdin=subprocess.PIPE)

        # Wait for server to start.
        self.mappings = mappings
        server_started = self.wait_for_action(
            self.is_server_running_on_all_ports)

        # Our process terminated already
        if not server_started or self._process.returncode != None:
            raise google.httpd_utils.HttpdNotStarted('Failed to start httpd.')

        _log.debug("Server successfully started")

    # TODO(deanm): Find a nicer way to shutdown cleanly.  Our log files are
    # probably not being flushed, etc... why doesn't our python have os.kill ?

    def stop(self, force=False):
        if not force and not self.is_running():
            return

        httpd_pid = None
        if self._process:
            httpd_pid = self._process.pid
        self._port_obj._shut_down_http_server(httpd_pid)

        if self._process:
            # wait() is not threadsafe and can throw OSError due to:
            # http://bugs.python.org/issue1731717
            self._process.wait()
            self._process = None
