#!/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', '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):
    if not os.path.isfile(bundle_path):
        raise ValueError(f"Can't find a bundle file at path: {bundle_path}")

    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-docker.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'{test_script} --platform={platform} {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'{test_script} --platform={platform} {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('--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)


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