#!/usr/bin/env python3
#
# Copyright (C) 2011, 2012, 2017, 2021 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 os
import sys
import optparse

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


try:
    from gi.repository import Gio, GLib
except ImportError:
    # We don't require gi to be installed outside the sandbox
    if flatpakutils.is_sandboxed() or jhbuildutils.enter_jhbuild_environment_if_available("gtk"):
        raise

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

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

    def _ensure_accessibility_service_is_running(self):
        # The a11y service is DBus activatable so we simply need to call it to ensure it
        # has been started.
        try:
            proxy = Gio.DBusProxy.new_for_bus_sync(Gio.BusType.SESSION,
                                                   Gio.DBusProxyFlags.NONE,
                                                   None,
                                                   'org.a11y.Bus',
                                                   '/org/a11y/bus',
                                                   'org.a11y.Bus',
                                                   None)

            # After this returns we know the bus is setup, the return value doesn't matter.
            proxy.GetAddress()
        except GLib.Error as e:
            sys.stderr.write("Failed to talk to the accessibility service: {}\n".format(e.message))
            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._ensure_accessibility_service_is_running():
            print("Could not start accessibility bus, so disabling TestWebKitAccessibility")
            self._disabled_tests.append("WebKit2Gtk/TestWebKitAccessibility")

    def _tear_down_testing_environment(self):
        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", "TestJavaScriptCore"]

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