#!/usr/bin/env python3
#
# Copyright (C) 2024 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT OWNER OR 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 argparse
import os
import sys
import tempfile
import tarfile

MYDIR = os.path.normpath(os.path.join(os.path.dirname(__file__)))
top_level_directory = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', '..'))
sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'Scripts'))
sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'jhbuild'))
sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'Scripts', 'webkitpy'))


# Executes the command and returns 0 if it was sucessful, otherwise returns a number => 1
def run_cmd(cmd):
    sys_retcode = os.system(cmd)
    if os.WIFEXITED(sys_retcode):
        return abs(os.WEXITSTATUS(sys_retcode))
    if os.WIFSIGNALED(sys_retcode):
        signumber = os.WTERMSIG(sys_retcode)
        print(f'ERROR: The process "{cmd}" was terminated with signal: {signumber}', file=sys.stderr)
        return abs(signumber)
    if os.WIFSTOPPED(status):
        signumber = os.WSTOPSIG(sys_retcode)
        print(f'ERROR: The process "{cmd}" was stopped with signal: {signumber}', file=sys.stderr)
        return abs(signumber)
    return max(sys_retcode, 1)


def tests_webdriver_minibroser(platform, bundle_type, bundle_path, headless):
    if not os.path.isfile(bundle_path):
        raise ValueError(f"Can't find a bundle file at path: {bundle_path}")

    headless_arg = '--headless' if headless else ''
    xwrap = 'xvfb-run -a ' if headless and platform == 'gtk' else ''

    if bundle_type == 'distro-specific':
        # This only works if executing on the same distro than created
        test_script = os.path.join(MYDIR,'webkitpy/binary_bundling/tests/webdriver/test_webdriver_bundle.py')
    elif bundle_type == 'universal':
        test_script = os.path.join(MYDIR,'webkitpy/binary_bundling/tests/webdriver/run-webdriver-tests-bundle-podman.sh')
    else:
        raise NotImplementedError(f'Unknown bundle type: {bundle_type}')

    if not (os.path.isfile(test_script) and os.access(test_script, os.X_OK)):
        raise RuntimeError(f"Can't find the test script at the expected path: {test_script}")

    # The test runner for the universal bundle handles itself uncompressing the bundle
    if bundle_type == 'universal':
        retcode = run_cmd(f'{xwrap}{test_script} --platform={platform} {headless_arg} {bundle_path}')
        return retcode

    # Handle here uncompressing the bundle for the distro-specific tests
    with tempfile.TemporaryDirectory() as temp_dir:
        if bundle_path.endswith('.tar.xz'):
            with tarfile.open(bundle_path, 'r:xz') as tar:
                tar.extractall(path=temp_dir)
        elif file_path.endswith('.zip'):
            with zipfile.ZipFile(bundle_path, 'r') as zip_ref:
                zip_ref.extractall(temp_dir)
        else:
            raise ValueError("Unsupported file format. Only .tar.xz and .zip are supported.")

        retcode = run_cmd(f'{xwrap}{test_script} --platform={platform} {headless_arg} {temp_dir}')
        return retcode


def main():
    parser = argparse.ArgumentParser('usage: %prog [options]')
    parser.add_argument('--platform', dest='platform', choices=['gtk', 'wpe'], required=True,
                        help='The WebKit port of the bundle to be tested')
    parser.add_argument("--no-headless", dest="headless", action="store_false", help="Do not run in headless mode")
    parser.add_argument('--bundle-type', dest='bundle_type', choices=['universal', 'distro-specific'], required=True,
                        help='Select universal if the bundle was created with "--syslibs=bundle-all" or select distro-specific otherwise')
    parser.add_argument('bundle_path', action='store', help='Path to the compressed bundle file')
    options = parser.parse_args()

    return tests_webdriver_minibroser(options.platform, options.bundle_type, options.bundle_path, options.headless)


if __name__ == '__main__':
    sys.exit(main())
