#!/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", "flatpak"))
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
import flatpakutils
from api_test_runner import TestRunner, add_options

class GtkTestRunner(TestRunner):
    TestRunner.TEST_TARGETS = [ "WebKit2Gtk", "TestWebKit", "TestJSC", "TestWTF", "TestWebCore" ]

    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("WebKit2Gtk/TestWebKitAccessibility")

    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"] or os.path.basename(test_program) in ["TestJSC"]

    def is_google_test(self, test_program):
        return os.path.basename(test_program) in ["TestWebKit", "TestWTF", "TestWebCore"]

    def is_qt_test(self, test_program):
        return False

if __name__ == "__main__":
    flatpakutils.run_in_sandbox_if_available(sys.argv)
    if not flatpakutils.is_sandboxed() and not jhbuildutils.enter_jhbuild_environment_if_available("gtk"):
        print '***'
        print '*** Warning: jhbuild environment not present and not running in flatpak.'
        print '*** Run update-webkitgtk-libs or update-webkitgtk-flatpak 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())
