#!/usr/bin/env python
#
# Copyright (C) 2011, 2012, 2017 Igalia S.L.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this library; see the file COPYING.LIB.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.

import logging
import subprocess
import os
import sys
import optparse
from gi.repository import Gio, GLib

top_level_directory = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", ".."))
sys.path.insert(0, os.path.join(top_level_directory, "Tools", "jhbuild"))
sys.path.insert(0, os.path.join(top_level_directory, "Tools", "glib"))
import common
import jhbuildutils
from api_test_runner import TestRunner, add_options

class GtkTestRunner(TestRunner):
    TestRunner.TEST_DIRS = [ "WebKit2Gtk", "WebKit", "JavaScriptCore", "WTF", "WebCore" ]

    def __init__(self, options, tests=[]):
        super(GtkTestRunner, self).__init__("gtk", options, tests)

        # These SPI daemons need to be active for the accessibility tests to work.
        self._spi_registryd = None
        self._spi_bus_launcher = None

    def _lookup_atspi2_binary(self, filename):
        exec_prefix = common.pkg_config_file_variable('atspi-2', 'exec_prefix')
        if not exec_prefix:
            return None
        for path in ['libexec', 'lib/at-spi2-core', 'lib32/at-spi2-core', 'lib64/at-spi2-core']:
            filepath = os.path.join(exec_prefix, path, filename)
            if os.path.isfile(filepath):
                return filepath

        return None

    def _wait_for_accessibility_bus(self):
        def timeout_accessibility_bus():
            self._accessibility_bus_found = False
            sys.stderr.write("Timeout waiting for the accesibility bus.\n")
            sys.stderr.flush()
            loop.quit()
        # Backup current environment, and temporally set the test one.
        oldenv = dict(os.environ)
        os.environ.clear()
        os.environ.update(self._test_env)
        # We spin a main loop until the bus name appears on DBus.
        self._accessibility_bus_found = True
        loop = GLib.MainLoop()
        Gio.bus_watch_name(Gio.BusType.SESSION, 'org.a11y.Bus', Gio.BusNameWatcherFlags.NONE,
                           lambda *args: loop.quit(), None)
        GLib.timeout_add_seconds(5, timeout_accessibility_bus)
        loop.run()
        # Restore previous environment.
        os.environ.clear()
        os.environ.update(oldenv)
        return self._accessibility_bus_found

    def _start_accessibility_daemons(self):
        spi_bus_launcher_path = self._lookup_atspi2_binary('at-spi-bus-launcher')
        spi_registryd_path = self._lookup_atspi2_binary('at-spi2-registryd')
        if not spi_bus_launcher_path or not spi_registryd_path:
            return False

        try:
            self._spi_bus_launcher = subprocess.Popen([spi_bus_launcher_path], env=self._test_env)
        except:
            sys.stderr.write("Failed to launch the accessibility bus\n")
            sys.stderr.flush()
            return False

        # We need to wait until the SPI bus is launched before trying to start the SPI registry.
        if not self._wait_for_accessibility_bus():
            sys.stderr.write("Failed checking the accessibility bus within D-Bus\n")
            sys.stderr.flush()
            return False

        try:
            self._spi_registryd = subprocess.Popen([spi_registryd_path], env=self._test_env)
        except:
            sys.stderr.write("Failed to launch the accessibility registry\n")
            sys.stderr.flush()
            return False

        return True

    def _setup_testing_environment(self):
        super(GtkTestRunner, self)._setup_testing_environment()

        # If we cannot start the accessibility daemons, we can just skip the accessibility tests.
        if not self._start_accessibility_daemons():
            print "Could not start accessibility bus, so disabling TestWebKitAccessibility"
            self._disabled_tests.append("WebKit2APITests/TestWebKitAccessibility")
        return True

    def _tear_down_testing_environment(self):
        if self._spi_registryd:
            self._spi_registryd.terminate()
        if self._spi_bus_launcher:
            self._spi_bus_launcher.terminate()
        super(GtkTestRunner, self)._tear_down_testing_environment()

    def is_glib_test(self, test_program):
        return os.path.basename(os.path.dirname(test_program)) in ["WebKit2Gtk", "JavaScriptCore"]

    def is_google_test(self, test_program):
        return os.path.basename(os.path.dirname(test_program)) in ["WebKit", "WTF", "WebCore",  "WebCoreGtk"]

if __name__ == "__main__":
    if not jhbuildutils.enter_jhbuild_environment_if_available("gtk"):
        print "***"
        print "*** Warning: jhbuild environment not present. Run update-webkitgtk-libs before build-webkit to ensure proper testing."
        print "***"

    option_parser = optparse.OptionParser(usage='usage: %prog [options] [test...]')
    add_options(option_parser);
    option_parser.add_option('--display-server', choices=['xvfb', 'xorg', 'weston', 'wayland'], default='xvfb',
                             help='"xvfb": Use a virtualized X11 server. "xorg": Use the current X11 session. '
                                  '"weston": Use a virtualized Weston server. "wayland": Use the current wayland session.'),
    options, args = option_parser.parse_args()

    logging.basicConfig(level=logging.INFO, format="%(message)s")

    runner = GtkTestRunner(options, args)
    sys.exit(runner.run_tests())
