#!/usr/bin/env python

# Copyright (C) 2017 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 logging
import optparse
import sys

from webkitpy.common.host import Host
from webkitpy.webdriver_tests.webdriver_test_runner import WebDriverTestRunner
from webkitpy.common.system.logutils import configure_logging

_log = logging.getLogger(__name__)

option_parser = optparse.OptionParser(usage='usage: %prog [options] [test...]')
option_parser.add_option('--verbose', action='store_true', dest='verbose',
                         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('--release', action='store_const', const='Release', dest="configuration",
                         help='Set the configuration to Release')
option_parser.add_option('--debug', action='store_const', const='Debug', dest="configuration",
                         help='Set the configuration to Debug')
option_parser.add_option('--timeout', action='store', type='int', dest='timeout', default=10,
                         help='Time in seconds until a test times out (use 0 to disable)')
option_parser.add_option('--json-output', action='store', metavar="FILE",
                         help='Write results to JSON file at the given path')
option_parser.add_option('--display-server', choices=['xvfb', 'xorg', 'weston', 'wayland', 'headless'], 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.'
                              '"headless": Headless mode in current session')

options, args = option_parser.parse_args()

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

try:
    port = Host().port_factory.get(options.platform, options)
except NotImplementedError, e:
    _log.error(str(e))
    sys.exit(-1)

if port.name() in ['gtk', 'wpe']:
    import os

    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'))
    import flatpakutils
    flatpakutils.run_in_sandbox_if_available(sys.argv)
    if not flatpakutils.is_sandboxed():
        sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'jhbuild'))
        import jhbuildutils

        if not jhbuildutils.enter_jhbuild_environment_if_available(port.name()):
            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 '***'

port._display_server = options.display_server
runner = WebDriverTestRunner(port)
runner.run(args)
runner.teardown()
retval = runner.process_results()

if options.json_output is not None:
    runner.dump_results_to_json_file(options.json_output)

sys.exit(retval)

