# Copyright (C) 2018 Igalia S.L.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.

import argparse
import json
import logging
import optparse
import os
import sys

from webkitpy.common.host import Host
from webkitpy.common.system.logutils import configure_logging
from webkitpy.common.webkit_finder import WebKitFinder
from webkitpy.w3c.common import WPTPaths
from webkitpy.w3c.test_downloader import TestDownloader
from webkitpy.webdriver_tests.webdriver_driver import create_driver

_log = logging.getLogger(__name__)


def main(script_name, argv):
    options, args = parse_args(argv)

    configure_logging(logging.DEBUG if options.verbose else logging.INFO)

    # Determine Port for the specified platform.
    host = Host()
    try:
        port = host.port_factory.get(options.platform, options)
    except NotImplementedError as e:
        _log.error(str(e))
        sys.exit(-1)

    runner = WPTRunner(port, port.host, script_name, options)
    # If necessary, inject the jhbuild wrapper or re-run in flatpak sandbox.
    if port.name() in ['gtk', 'wpe']:
        filesystem = host.filesystem

        top_level_directory = filesystem.normpath(filesystem.join(filesystem.dirname(__file__), '..', '..', '..', '..'))
        sys.path.insert(0, filesystem.join(top_level_directory, 'Tools', 'flatpak'))
        import flatpakutils
        if not flatpakutils.is_sandboxed() and flatpakutils.check_flatpak(verbose=False):
            flatpak_runner = flatpakutils.WebkitFlatpak.load_from_args(sys.argv)
            if flatpak_runner.clean_args() and flatpak_runner.has_environment():
                if not runner.prepare_wpt_checkout():
                    sys.exit(1)

                hostfilename = os.path.join(flatpak_runner.build_path, "wpt_etc_hosts")
                with open(hostfilename, "w") as stdout:
                    flatpak_runner.run_in_sandbox(os.path.join(options.wpt_checkout, "wpt"), "make-hosts-file", stdout=stdout)

                sys.exit(flatpak_runner.run_in_sandbox(*sys.argv,
                    extra_flatpak_args=['--bind-mount=/etc/hosts=%s' % hostfilename]))

        sys.path.insert(0, filesystem.join(top_level_directory, 'Tools', 'jhbuild'))
        import jhbuildutils

        if not flatpakutils.is_sandboxed() and not jhbuildutils.enter_jhbuild_environment_if_available(port.name()):
            _log.warning('jhbuild environment not present. Run update-webkitgtk-libs before build-webkit to ensure proper testing.')

    # Create the Port-specific driver.
    port._display_server = options.display_server
    display_driver = port.create_driver(worker_number=0, no_timeout=True)._make_driver(pixel_tests=False)
    if not display_driver.check_driver(port):
        raise RuntimeError("Failed to check driver %s" % display_driver.__class__.__name__)
    os.environ.update(display_driver._setup_environ_for_test())

    if not options.child_processes:
        options.child_processes = os.environ.get("WEBKIT_TEST_CHILD_PROCESSES",
                                                 str(port.default_child_processes()))

    if not runner.run(args):
        sys.exit(1)


def parse_args(args):
    option_parser = optparse.OptionParser(usage='usage: %prog [options] [test...]')
    option_parser.add_option('--verbose', action='store_true',
                             help='Show debug message')
    option_parser.add_option('--platform', action='store',
                             help='Platform to use (e.g., "gtk")')
    option_parser.add_option('--gtk', action='store_const', dest='platform', const='gtk',
                             help='Alias for --platform=gtk')
    option_parser.add_option('--wpe', action='store_const', dest='platform', const='wpe',
                             help='Alias for --platform=wpe')
    option_parser.add_option('--child-processes',
                             help='Number of tests to run in parallel'),
    option_parser.add_option('--wpt-checkout', default=None,
                             help='web-platform-tests repository location')
    option_parser.add_option('--wpt-metadata', default=None,
                             help='web-platform-tests metadata location')
    option_parser.add_option('--wpt-manifest', default=None,
                             help='web-platform-tests manifest location')
    option_parser.add_option('--wpt-include-manifest', default=None,
                             help='web-platform-tests include manifest location')
    option_parser.add_option('--display-server', choices=['headless', 'xvfb', 'xorg', 'weston', 'wayland'], default='xvfb',
                             help='"headless": Use headless mode. "xvfb": Use a virtualized X11 server. '
                                  '"xorg": Use the current X11 session. "weston": Use a virtualized Weston server. '
                                  '"wayland": Use the current wayland session.')

    return option_parser.parse_args(args)


def create_webdriver(port):
    return create_driver(port)


def spawn_wpt(script_name, wpt_checkout, wpt_args):
    # Import the WPT python module.
    sys.path.insert(0, wpt_checkout)
    try:
        from tools.wpt import wpt
    except ImportError:
        _log.error("Failed to import wpt Python modules from the web-platform-tests directory")
        sys.exit(-1)

    wpt.main(script_name, wpt_args)


class WPTRunner(object):
    def __init__(self, port, host, script_name, options, downloader_class=TestDownloader,
        create_webdriver_func=create_webdriver, spawn_wpt_func=spawn_wpt):
        self._port = port
        self._host = host
        self._finder = WebKitFinder(self._host.filesystem)

        self._script_name = script_name
        self._options = options

        self._downloader_class = downloader_class
        self._create_webdriver_func = create_webdriver_func
        self._spawn_wpt_func = spawn_wpt_func

    def prepare_wpt_checkout(self):
        if not self._options.wpt_checkout:
            test_downloader = self._downloader_class(WPTPaths.checkout_directory(self._finder),
                self._host, self._downloader_class.default_options())
            test_downloader.clone_tests()
            self._options.wpt_checkout = WPTPaths.wpt_checkout_path(self._finder)

        if not self._options.wpt_checkout or not self._host.filesystem.exists(self._options.wpt_checkout):
            _log.error("Valid web-platform-tests directory required")
            return False
        return True

    def run(self, args):
        if not self.prepare_wpt_checkout():
            return False

        # Construct the WebDriver instance and run WPT tests via the 'webkit' product.
        webdriver = self._create_webdriver_func(self._port)

        wpt_args = ["run", "--webkit-port={}".format(self._port.name()),
            "--processes={}".format(self._options.child_processes)]
        if self._options.wpt_metadata:
            wpt_args += ["--metadata={}".format(self._options.wpt_metadata)]
        if self._options.wpt_manifest:
            wpt_args += ["--manifest={}".format(self._options.wpt_manifest)]
        if self._options.wpt_include_manifest:
            wpt_args += ["--include-manifest={}".format(self._options.wpt_include_manifest)]
        wpt_args += ["--webdriver-binary={}".format(webdriver.binary_path()),
            "--binary={}".format(webdriver.browser_path())]
        wpt_args += ["--binary-arg={}".format(arg) for arg in webdriver.browser_args()]
        wpt_args += ["webkit"] + args

        self._spawn_wpt_func(self._script_name, self._options.wpt_checkout, wpt_args)
        return True
