#!/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_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")

    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"]

    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())
