# -*- coding: utf-8 -*-
# Copyright (C) 2017 Igalia S.L.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This program 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301, USA.
import argparse
import atexit
import logging
try:
    import configparser
except ImportError:
    import ConfigParser as configparser
from contextlib import contextmanager
import errno
import json
import multiprocessing
import os
import shlex
import shutil
import signal
import subprocess
import sys
import tempfile
import re
import platform

SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
WEBKIT_SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(SCRIPT_DIR, "..", "..")))
sys.path.insert(0, os.path.join(WEBKIT_SOURCE_DIR, "Tools", "Scripts"))
from webkitpy.common.system.logutils import configure_logging
from webkitcorepy import string_utils
import toml
import json

try:
    from urllib.parse import urlparse  # pylint: disable=E0611
except ImportError:
    from urlparse import urlparse

try:
    from urllib.request import urlopen  # pylint: disable=E0611
except ImportError:
    from urllib2 import urlopen

try:
    from contextlib import nullcontext
except ImportError:
    @contextmanager
    def nullcontext(enter_result=None):
        yield enter_result

FLATPAK_REQUIRED_VERSION = "1.4.4"

_log = logging.getLogger(__name__)

BUILD_ROOT_DIR_NAME = 'WebKitBuild'

# This path doesn't take $WEBKIT_OUTPUTDIR in account because the standalone toolchains
# paths depend on it and those are also hard-coded in the generated sccache config.
DEFAULT_BUILD_ROOT = os.path.join(WEBKIT_SOURCE_DIR, BUILD_ROOT_DIR_NAME)
BUILD_ROOT = os.path.join(os.environ.get("WEBKIT_OUTPUTDIR", WEBKIT_SOURCE_DIR), BUILD_ROOT_DIR_NAME)
FLATPAK_USER_DIR_PATH = os.path.realpath(os.path.join(DEFAULT_BUILD_ROOT, "UserFlatpak"))

DEFAULT_SCCACHE_SCHEDULER='https://sccache.igalia.com'

# Where the source folder is mounted inside the sandbox.
SANDBOX_SOURCE_ROOT = "/app/webkit"

# Our SDK branch matches with the FDO SDK branch. When updating the FDO SDK release branch
# in our SDK build definitions please don't forget to update the version here as well.
SDK_BRANCH = "21.08"

WEBKIT_SDK_FLATPAK_REPO_URL = "https://software.igalia.com/flatpak-refs/webkit-sdk.flatpakrepo"
WEBKIT_SDK_GPG_PUBKEY_URL = "https://software.igalia.com/flatpak-refs/webkit-sdk-pubkey.gpg"
WEBKIT_SDK_REPO_URL = "https://software.igalia.com/webkit-sdk-repo/"

is_colored_output_supported = False
try:
    import curses
    assert sys.stdout.isatty()
    curses.setupterm()
    assert curses.tigetnum("colors") > 0
except Exception:
    is_colored_output_supported = False
else:
    is_colored_output_supported = True

class Colors:
    HEADER = "\033[95m"
    OKBLUE = "\033[94m"
    OKGREEN = "\033[92m"
    WARNING = "\033[93m"
    FAIL = "\033[91m"
    ENDC = "\033[0m"


class Console:

    quiet = False

    @classmethod
    def message(cls, str_format, *args):
        if cls.quiet:
            return

        if args:
            print(str_format % args)
        else:
            print(str_format)

        # Flush so that messages are printed at the right time
        # as we use many subprocesses.
        sys.stdout.flush()

    @classmethod
    def colored_message_if_supported(cls, color, str_format, *args):
        if args:
            msg = str_format % args
        else:
            msg = str_format

        if is_colored_output_supported:
            cls.message("\n%s%s%s", color, msg, Colors.ENDC)
        else:
            cls.message(msg)

    @classmethod
    def error_message(cls, str_format, *args):
        cls.colored_message_if_supported(Colors.FAIL, str_format, *args)

    @classmethod
    def warning_message(cls, str_format, *args):
        cls.colored_message_if_supported(Colors.WARNING, str_format, *args)


def run_sanitized(command, gather_output=False, ignore_stderr=False, env=None, **kwargs):
    """ Runs a command in a santized environment and optionally returns decoded output or raises
        subprocess.CalledProcessError
    """
    if env:
        sanitized_env = env.copy()
    else:
        sanitized_env = os.environ.copy()

    # We need clean output free of debug messages
    try:
        del sanitized_env["G_MESSAGES_DEBUG"]
    except KeyError:
        pass

    _log.debug("Running %s", " ".join(command))
    keywords = kwargs
    keywords['env'] = sanitized_env
    if gather_output:
        if ignore_stderr:
            with open(os.devnull, 'w') as devnull:
                output = subprocess.check_output(command, stderr=devnull, **keywords)
        else:
            output = subprocess.check_output(command, **keywords)
        return output.strip().decode('utf-8')
    else:
        keywords["stdout"] = sys.stdout
        if ignore_stderr:
            with open(os.devnull, 'w') as devnull:
                keywords["stderr"] = devnull
                return subprocess.check_call(command, **keywords)
        else:
            return subprocess.check_call(command, **keywords)


def check_flatpak(verbose=True):
    # Flatpak is only supported on Linux.
    if not sys.platform.startswith("linux"):
        return ()

    required_version = FLATPAK_REQUIRED_VERSION
    try:
        output = run_sanitized(["flatpak", "--version"], gather_output=True)
    except (subprocess.CalledProcessError, OSError):
        if verbose:
            Console.error_message("You need to install flatpak >= %s"
                                  " to be able to use the '%s' script.\n\n"
                                  "You can find some informations about"
                                  " how to install it for your distribution at:\n"
                                  "    * https://flatpak.org/\n", required_version,
                                  sys.argv[0])
            return ()

    def comparable_version(version):
        return tuple(map(int, (version.split("."))))

    version = output.split(" ")[1].strip("\n")
    current_version = comparable_version(version)
    if current_version < comparable_version(required_version):
        Console.error_message("flatpak %s required but %s found. Please update and try again\n",
                              required_version, version)
        return ()

    return current_version


def convert_webkit_source_path_to_sandbox_path(source_path):
    '''Convert a path in the WebKit source directory to the same path in the
       sandboxed source diretory. '''
    return source_path.replace(WEBKIT_SOURCE_DIR, SANDBOX_SOURCE_ROOT)


def convert_sandbox_path_to_webkit_source_path(sandbox_path):
    # For now this supports only files in the /app/webkit path
    return sandbox_path.replace(SANDBOX_SOURCE_ROOT, WEBKIT_SOURCE_DIR)


def get_build_dir(platform, build_type):
    return os.path.join(BUILD_ROOT, platform, build_type)

class FlatpakObject:

    def __init__(self, user):
        self.user = user

    def flatpak(self, command, *args, **kwargs):
        comment = kwargs.pop("comment", None)
        gather_output = kwargs.get("gather_output", False)
        if comment:
            Console.message(comment)

        command = ["flatpak", command]
        help_output = run_sanitized(command + ["--help"], gather_output=True)
        if self.user and "--user" in help_output:
            command.append("--user")
        if "--assumeyes" in help_output:
            command.append("--assumeyes")
        if "--noninteractive" in help_output and gather_output:
            command.append("--noninteractive")

        command.extend(args)

        return run_sanitized(command, **kwargs)

    def version(self, ref_id):
        try:
            output = self.flatpak("info", ref_id, gather_output=True, ignore_stderr=True)
        except subprocess.CalledProcessError:
            # ref is likely not installed
            return ""
        for line in output.splitlines():
            tokens = line.split(":")
            if len(tokens) != 2:
                continue
            if tokens[0].strip().lower() == "version":
                return tokens[1].strip()
        return ""

    def flatpak_update(self):
        remote = "webkit-sdk"
        try:
            self.flatpak("remote-ls", remote, gather_output=True)
        except subprocess.CalledProcessError as error:
            if error.output.lower().find(b"key expired"):
                Console.message("WebKit SDK GPG key expired, synchronizing with remote")
                with tempfile.NamedTemporaryFile() as tmpfile:
                    fd = urlopen(WEBKIT_SDK_GPG_PUBKEY_URL)
                    tmpfile.write(fd.read())
                    tmpfile.flush()
                    self.flatpak("remote-modify", "--gpg-import=" + tmpfile.name, remote)

        self.flatpak("update", comment="Updating Flatpak environment")

class FlatpakPackages(FlatpakObject):

    def __init__(self, repos, user=True):
        FlatpakObject.__init__(self, user=user)
        self.repos = repos
        self.update()

    def update(self):
        self.packages = []
        out = self.flatpak("list", "--columns=application,arch,branch,origin", "-a", gather_output=True)
        package_defs = [line for line in out.split("\n") if line]
        for package_def in package_defs:
            name, arch, branch, origin = package_def.split("\t")

            # If installed from a file, the package is in no repo
            repo = self.repos.repos.get(origin)
            self.packages.append(FlatpakPackage(name, branch, repo, arch))

    def __iter__(self):
        for package in self.packages:
            yield package


class FlatpakRepos(FlatpakObject):

    def __init__(self, repos, user=True):
        FlatpakObject.__init__(self, user=user)
        self.update()

        updated = False
        for repo in repos:
            updated = self.add(repo, update=False) or updated

        # Only fetch the remote and package list again if we updated anything.
        if updated:
            self.update()

    def update(self):
        self.repos = {}
        out = self.flatpak("remote-list", "--columns=name,title,url", gather_output=True)
        remotes = [line for line in out.split("\n") if line]
        for remote in remotes:
            name, title, url = remote.split("\t")
            parsed_url = urlparse(url)
            if not parsed_url.scheme:
                Console.message("No valid URI found for: %s", remote)
                continue

            self.repos[name] = FlatpakRepo(name=name, url=url, desc=title, repos=self)

        self.packages = FlatpakPackages(self)

    def add(self, repo, update=True, override=True):
        try:
            repo.repos = self

            same_name = None
            for name, tmprepo in self.repos.items():
                if repo.url == tmprepo.url:
                    return False
                elif repo.name == name:
                    same_name = tmprepo

            if same_name:
                if override and same_name.url != repo.url:
                    self.flatpak("remote-modify", repo.name, "--url=" + repo.url)
                    same_name.url = repo.url
                    return True
                else:
                    return False

            args = ["remote-add", repo.name, "--if-not-exists"]
            if repo.repo_file:
                args.extend(["--from", repo.repo_file.name])
            else:
                args.extend(["--no-gpg-verify", repo.url])
            self.flatpak(*args, comment="Adding repo %s" % repo.name)
            return True
        finally:
            if update:
                self.packages = FlatpakPackages(self)

    def is_package_installed(self, name, branch=None, arch=None):
        for package in self.packages:
            if name != package.name:
                continue
            if branch and branch != package.branch:
                continue
            if arch and arch != package.arch:
                continue
            return True
        return False


class FlatpakRepo(FlatpakObject):

    def __init__(self, name, desc=None, url=None,
                 repo_file=None, user=True, repos=None):
        FlatpakObject.__init__(self, user=user)

        self.name = name
        self.url = url
        self.desc = desc
        self.repo_file_name = repo_file
        self._repo_file = None
        self.repos = repos
        assert name
        if repo_file and not url:
            repo = configparser.ConfigParser()
            repo.read(self.repo_file.name)
            try:
                self.url = repo["Flatpak Repo"]["Url"]
            except AttributeError:
                self.url = repo.get("Flatpak Repo", "Url")
        else:
            assert url

    @property
    def repo_file(self):
        if self._repo_file:
            return self._repo_file

        if not self.repo_file_name:
            return None

        self._repo_file = tempfile.NamedTemporaryFile(mode="wb")
        self._repo_file.write(urlopen(self.repo_file_name).read())
        self._repo_file.flush()

        return self._repo_file


class FlatpakPackage(FlatpakObject):
    """A flatpak app."""

    def __init__(self, name, branch, repo, arch, user=True, hash=None):
        FlatpakObject.__init__(self, user=user)

        self.name = name
        self.branch = str(branch)
        self.repo = repo
        self.arch = arch

    def __repr__(self):
        return "%s/%s/%s %s" % (self.name, self.arch, self.branch, self.repo.name)

    def __str__(self):
        return "%s/%s/%s" % (self.name, self.arch, self.branch)

    def is_installed(self, branch):
        # Bundles installed from files do not have repositories.
        if not self.repo:
            return True
        return self.repo.repos.is_package_installed(self.name, branch, self.arch)

    def install(self):
        if not self.repo:
            return False

        branch = self.branch
        args = ("install", self.repo.name, self.name, "--reinstall", branch)
        comment = "Installing from " + self.repo.name + " " + self.name + " " + self.arch + " " + branch
        self.flatpak(*args, comment=comment)
        self.repo.repos.packages.update()

@contextmanager
def disable_signals(signals=[signal.SIGINT, signal.SIGTERM, signal.SIGHUP]):
    old_signal_handlers = []

    for disabled_signal in signals:
        handler = signal.getsignal(disabled_signal)
        if handler:
            old_signal_handlers.append((disabled_signal, handler))
        signal.signal(disabled_signal, signal.SIG_IGN)

    yield

    for disabled_signal, previous_handler in old_signal_handlers:
        signal.signal(disabled_signal, previous_handler)


def extract_extra_command_args(args):
    """Takes a list of unparsed args and splits them at '--' to pass to subprocesses."""
    try:
        return args[args.index('--') + 1:]
    except ValueError:
        return []

class WebkitFlatpak:

    @staticmethod
    def load_from_args(args=None, add_help=True):
        self = WebkitFlatpak()

        parser = argparse.ArgumentParser(prog="webkit-flatpak", add_help=add_help)
        general = parser.add_argument_group("General")
        general.add_argument('--verbose', action='store_true', help='Show debug messages')
        general.add_argument('--version', action='store_true', help='Show SDK version', dest="show_version")
        type_group = parser.add_mutually_exclusive_group()
        type_group.add_argument("--debug",
                                help="Compile with Debug configuration, also installs Sdk debug symbols.",
                                dest='build_type', action="store_const", const="Debug")
        type_group.add_argument("--release", help="Compile with Release configuration.",
                                dest='build_type', action="store_const", const="Release")
        general.add_argument('--gtk', action='store_const', dest='platform', const='gtk',
                             help='Setup build directory for the GTK port')
        general.add_argument('--wpe', action='store_const', dest='platform', const='wpe',
                             help=('Setup build directory for the WPE port'))
        general.add_argument("-u", "--update", dest="update",
                             action="store_true",
                             help="Update the SDK")
        general.add_argument("-bdeps", "--build-local-deps", dest="build_local_deps",
                             action="store_true", help="Force rebuilding local dependencies")
        general.add_argument("-q", "--quiet", dest="quiet",
                             action="store_true",
                             help="Do not print anything")
        general.add_argument("-c", "--command",
                             nargs=argparse.REMAINDER,
                             help="The command to run in the sandbox",
                             dest="user_command")
        general.add_argument('--available', action='store_true', dest="check_available", help='Check if required dependencies are available.'),
        general.add_argument("--repo", help="Filesystem absolute path to the Flatpak repository to use", dest="user_repo")

        distributed_build_options = parser.add_argument_group("Distributed building")
        distributed_build_options.add_argument("--use-icecream", dest="use_icecream", help="Use the distributed icecream (icecc) compiler.", action="store_true")
        distributed_build_options.add_argument("-r", "--regenerate-toolchains", dest="regenerate_toolchains", action="store_true",
                                               help="Regenerate IceCC/SCCache standalone toolchain archives")
        distributed_build_options.add_argument("-t", "--sccache-token", dest="sccache_token",
                                               help="sccache authentication token")
        distributed_build_options.add_argument("-s", "--sccache-scheduler", dest="sccache_scheduler",
                                               help="sccache scheduler URL (default: %s)" % DEFAULT_SCCACHE_SCHEDULER)

        debugoptions = parser.add_argument_group("Debugging")
        debugoptions.add_argument("--gdb", nargs="?", help="Activate gdb, passing extra args to it if wanted.")
        debugoptions.add_argument("--gdb-stack-trace", dest="gdb_stack_trace", nargs="?",
                                  help="Dump the stacktrace to stdout. The argument is a timestamp to be parsed by coredumpctl.")
        debugoptions.add_argument("-m", "--coredumpctl-matches", default="", help='Arguments to pass to gdb.')

        buildoptions = parser.add_argument_group("Extra build arguments")
        buildoptions.add_argument("--cmakeargs",
                                  help="One or more optional CMake flags (e.g. --cmakeargs=\"-DFOO=bar -DCMAKE_PREFIX_PATH=/usr/local\")")

        parsing_namespace, self.args = parser.parse_known_args(args=args, namespace=self)
        self.extra_command_args = extract_extra_command_args(parsing_namespace.args)

        if not self.build_type:
            self.build_type = "Release"

        if os.environ.get('CCACHE_PREFIX') == 'icecc':
            self.use_icecream = True

        verbose = os.environ.get('WEBKIT_FLATPAK_SDK_VERBOSE')
        if (not self.verbose) and (verbose is not None):
            self.verbose = verbose != '0'

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

        if self.user_repo:
            if not os.path.exists(self.user_repo):
                _log.error('User repo at %s is not accessible\n' % self.user_repo)
                sys.exit(1)

        return self

    def __init__(self):
        self.sdk_repo = None
        self.runtime = None
        self.sdk = None
        self.user_repo = None

        self.show_version = False
        self.verbose = False
        self.quiet = False
        self.update = False
        self.args = []
        self.gdb_stack_trace = False

        self.release = False
        self.debug = False

        self.build_local_deps = False

        self.platform = "gtk"
        self.check_available = False
        self.user_command = []

        # debug options
        self.gdb = None
        self.coredumpctl_matches = ""

        # Extra build options
        self.cmakeargs = ""

        self.use_icecream = False
        self.icc_version = {}
        self.regenerate_toolchains = False
        self.sccache_token = ""
        self.sccache_scheduler = DEFAULT_SCCACHE_SCHEDULER

    def execute_command(self, args, stdout=None, stderr=None, env=None, keep_signals=True):
        if keep_signals:
            ctx_manager = nullcontext()
        else:
            ctx_manager = disable_signals()
        _log.debug('Running: %s\n' % ' '.join(string_utils.decode(arg) for arg in args))
        result = 0
        with ctx_manager:
            try:
                result = subprocess.check_call(args, stdout=stdout, stderr=stderr, env=env)
            except subprocess.CalledProcessError as err:
                if self.verbose:
                    cmd = ' '.join(string_utils.decode(arg) for arg in err.cmd)
                    message = "'%s' returned a non-zero exit code." % cmd
                    if stderr:
                        with open(stderr.name, 'r') as stderrf:
                            message += " Stderr: %s" % stderrf.read()
                    Console.error_message(message)
                return err.returncode
        return result

    def clean_args(self):
        if self.user_repo:
            os.environ["FLATPAK_USER_DIR"] = FLATPAK_USER_DIR_PATH + ".Local"
        else:
            os.environ["FLATPAK_USER_DIR"] = os.environ.get("WEBKIT_FLATPAK_USER_DIR", FLATPAK_USER_DIR_PATH)
        self.flatpak_build_path = os.environ["FLATPAK_USER_DIR"]
        try:
            os.makedirs(self.flatpak_build_path)
        except OSError as e:
            pass
        _log.debug("Using flatpak user dir: %s" % self.flatpak_build_path)

        self.platform = self.platform.upper()

        if self.gdb is None and '--gdb' in sys.argv:
            self.gdb = True

        self.config_file = os.path.join(self.flatpak_build_path, 'webkit_flatpak_config.json')
        self.sccache_config_file = os.path.join(self.flatpak_build_path, 'sccache.toml')

        self.build_path = get_build_dir(self.platform, self.build_type)
        _log.debug("Building %s port in %s" % (self.platform, self.build_path))

        self.toolchains_directory = os.path.join(self.flatpak_build_path, "Toolchains")
        if not os.path.isdir(self.toolchains_directory):
            os.makedirs(self.toolchains_directory)

        Console.quiet = self.quiet
        self.flatpak_version = check_flatpak()
        if not self.flatpak_version:
            return False

        self._reset_repository()

        try:
            with open(self.config_file) as config:
                json_config = json.load(config)
                self.icc_version = json_config['icecc_version']
        except IOError as e:
            pass

        return True

    def _reset_repository(self):
        url = WEBKIT_SDK_REPO_URL
        repo_file = WEBKIT_SDK_FLATPAK_REPO_URL
        if self.user_repo:
            url = "file://%s" % self.user_repo
            repo_file = None

        self.sdk_repo = FlatpakRepo("webkit-sdk", url=url, repo_file=repo_file)
        self.flathub_repo = FlatpakRepo("flathub", url="https://dl.flathub.org/repo/",
                                        repo_file="https://dl.flathub.org/repo/flathub.flatpakrepo")
        self.repos = FlatpakRepos([self.sdk_repo, self. flathub_repo])

    def setup_builddir(self):
        if os.path.exists(os.path.join(self.flatpak_build_path, "metadata")):
            return True

        if not self.check_installed_packages():
            return False

        self.sdk_repo.flatpak("build-init",
                              self.flatpak_build_path,
                              "org.webkit.Webkit",
                              str(self.sdk),
                              str(self.runtime),
                              self.sdk.branch)

        return True

    def setup_local_deps(self, building):
        if not os.environ.get('WEBKIT_SDK_LOCAL_DEPS'):
            if building:
                _log.debug("$WEBKIT_SDK_LOCAL_DEPS environment variable not set. Skipping local dependencies build")
            return {}

        src_dir = os.path.join(WEBKIT_SOURCE_DIR, 'Tools', 'flatpak', 'local-projects')
        build_dir = os.path.join(DEFAULT_BUILD_ROOT, 'deps-build')
        sandbox_build_dir = convert_webkit_source_path_to_sandbox_path(build_dir)
        if not os.path.exists(os.path.join(build_dir, 'build.ninja')):
            if not building:
                raise RuntimeError('Trying to enter deps-build env from %s but it is not built, make sure to rebuild webkit.', src_dir)

            projects = '-Dsubprojects=%s' % os.environ['WEBKIT_SDK_LOCAL_DEPS']
            options = shlex.split(os.environ.get('WEBKIT_SDK_LOCAL_DEPS_OPTIONS', ''))
            args = ['meson', projects]
            args.extend(options + [convert_webkit_source_path_to_sandbox_path(src_dir), sandbox_build_dir])
            self.run_in_sandbox(*args, building_local_deps=True, start_sccache=False)

        if building:
            Console.message("Building local dependencies from %s ", src_dir)
            if self.run_in_sandbox('meson', 'compile', '-C', sandbox_build_dir, building_local_deps=True, start_sccache=False) != 0:
                raise RuntimeError('Error while building local dependencies.')

        command = ['meson', 'devenv', '-C', sandbox_build_dir, '--dump']
        local_env = self.run_in_sandbox(*command, building_local_deps=True, start_sccache=False, gather_output=True)
        env = {}
        for line in [line for line in local_env.splitlines() if not line.startswith("export")]:
            tokens = line.split("=")
            var_name, contents = tokens[0], "=".join(tokens[1:])
            env[var_name] = contents
        return env

    def _merge_env_variables(self, environment, additional_environment):
        for var_name, value in additional_environment.items():
            if var_name not in environment:
                environment[var_name] = value
            else:
                if var_name.endswith('PATH'):
                    environment[var_name] = "%s:%s" % (environment[var_name], value)
        return environment

    def is_branch_build(self):
        try:
            with open(os.devnull, 'w') as devnull:
                rev_parse = subprocess.check_output(("git", "rev-parse", "--abbrev-ref", "HEAD"), stderr=devnull)
        except subprocess.CalledProcessError:
            # This is likely not a git checkout.
            return False
        git_branch_name = rev_parse.decode("utf-8").strip()
        for option_name in ("branch.%s.webKitBranchBuild" % git_branch_name,
                            "webKitBranchBuild"):
            try:
                with open(os.devnull, 'w') as devnull:
                    output = subprocess.check_output(("git", "config", "--bool", option_name), stderr=devnull).strip()
            except subprocess.CalledProcessError:
                continue

            if output == "true":
                return True
        return False

    def is_build_webkit(self, command):
        return command and "build-webkit" in os.path.basename(command)

    def is_build_jsc(self, command):
        return command and "build-jsc" in os.path.basename(command)

    def setup_a11y_proxy(self):
        try:
            output = subprocess.check_output(("gdbus", "call", "-e", "-d", "org.a11y.Bus", "-o", "/org/a11y/bus", "-m", "org.a11y.Bus.GetAddress"))
            a11y_bus_address = re.findall(br"'([^']+)", output)[0]  # Extract string from output from: ('unix:abstract=0000f',)
            _log.debug("Found a11y address {}".format(a11y_bus_address))
        except (subprocess.CalledProcessError, IndexError, FileNotFoundError) as e:
            _log.warning("Failed to get a11y address {}".format(e))
            return []

        dbus_proxy_path = shutil.which("xdg-dbus-proxy")
        if not dbus_proxy_path:
            _log.warning("Failed to find xdg-dbus-proxy. Can't forward a11y bus.")
            return []

        self.socket_dir = tempfile.TemporaryDirectory(prefix="webkit-flatpak-a11y-sockets-")
        self.a11y_socket = tempfile.NamedTemporaryFile(dir=self.socket_dir.name, delete=False)

        try:
            proxy_proc = subprocess.Popen((dbus_proxy_path, a11y_bus_address, self.a11y_socket.name))

            atexit.register(lambda: proxy_proc.terminate())
        except (subprocess.CalledProcessError) as e:
            _log.warning("Failed to run xdg-dbus-proxy {}. Can't forward a11y bus.".format(e))
            return []

        return [
            # FIXME: --session-bus is only a workaround for https://github.com/flatpak/flatpak/pull/4630
            "--session-bus",
            "--no-a11y-bus",
            "--filesystem=" + self.socket_dir.name,
            "--env=AT_SPI_BUS_ADDRESS=unix:path=" + self.a11y_socket.name,
        ]

    def run_in_sandbox(self, *args, **kwargs):
        if not self.setup_builddir():
            return 1
        extra_env_vars = kwargs.get("env", {})
        stdout = kwargs.get("stdout", sys.stdout)
        extra_flatpak_args = kwargs.get("extra_flatpak_args", [])
        start_sccache = kwargs.get("start_sccache", True)
        skip_icc = kwargs.get("skip_icc", False)
        building_local_deps = kwargs.get("building_local_deps", False)
        gather_output = kwargs.get("gather_output", False)

        if gather_output:
            start_sccache = False
            skip_icc = True

        if not isinstance(args, list):
            args = list(args)

        sandbox_build_path = os.path.join(SANDBOX_SOURCE_ROOT, BUILD_ROOT_DIR_NAME, self.build_type)
        sandbox_environment = {
            "TEST_RUNNER_INJECTED_BUNDLE_FILENAME": os.path.join(sandbox_build_path, "lib/libTestRunnerInjectedBundle.so"),
            "PATH": "/usr/lib/sdk/llvm13/bin:/usr/bin:/usr/lib/sdk/rust/bin/",
        }

        if not args:
            args.append("bash")

        if args:
            if gather_output:
                command = args[0]
            elif os.path.exists(args[0]):
                command = os.path.normpath(os.path.abspath(args[0]))
                # Take into account the fact that the webkit source dir is remounted inside the sandbox.
                args[0] = convert_webkit_source_path_to_sandbox_path(command)

            if args[0] == "bash":
                args.extend(['--noprofile', '--norc', '-i'])
                sandbox_environment["PS1"] = f"[📦🌐🐱 $FLATPAK_ID {self.platform}@{self.build_type} \\W]\\$ "
            if gather_output:
                building = False
            else:
                building = self.is_build_jsc(args[0]) or self.is_build_webkit(args[0])
        else:
            building = False

        flatpak_command = ["flatpak", "run",
                           "--user",
                           "--die-with-parent",
                           "--filesystem=host",
                           "--allow=devel",
                           "--talk-name=org.gtk.vfs",
                           "--talk-name=org.gtk.vfs.*"]

        flatpak_a11y_args = self.setup_a11y_proxy()
        flatpak_command.extend(flatpak_a11y_args)

        if not gather_output and args and self.is_build_webkit(args[0]) and not self.is_branch_build():
            # Ensure self.build_path exists.
            try:
                os.makedirs(self.build_path)
            except OSError as e:
                if e.errno != errno.EEXIST:
                    raise e

        share_network_option = "--share=network"

        if self.platform == 'WPE':
            flatpak_command.append(share_network_option)

        if not building:
            flatpak_command.extend([
                "--device=all",
                "--device=dri",
                "--share=ipc",
                "--share=network",
                "--socket=pulseaudio",
                "--socket=session-bus",
                "--socket=system-bus",
                "--socket=wayland",
                "--socket=x11",
                "--system-talk-name=org.a11y.Bus",
                "--system-talk-name=org.freedesktop.GeoClue2",
                "--talk-name=org.freedesktop.Flatpak",
                "--talk-name=org.freedesktop.secrets"
            ])

            sandbox_environment.update({
                "TZ": "America/Los_Angeles",
            })

        env_var_prefixes_to_keep = [
            "G",
            "CCACHE",
            "EGL",
            "GIGACAGE",
            "GTK",
            "ICECC",
            "JSC",
            "MESA",
            "LIBGL",
            "PIPEWIRE",
            "NICE",
            "RUST",
            "SCCACHE",
            "SPA",
            "WAYLAND",
            "WEBKIT",
            "WEBKIT2",
            "WPE",
        ]

        env_var_suffixes_to_keep = [
            "JSC_ARGS",
            "PROCESS_CMD_PREFIX",
            "WEBKIT_ARGS",
        ]

        env_vars_to_keep = [
            "CC",
            "CCACHE_PREFIX",
            "CFLAGS",
            "CXX",
            "CXXFLAGS",
            "DISPLAY",
            "JavaScriptCoreUseJIT",
            "LDFLAGS",
            "MAX_CPU_LOAD",
            "Malloc",
            "NUMBER_OF_PROCESSORS",
            "QML2_IMPORT_PATH",
            "RESULTS_SERVER_API_KEY",
            "SSLKEYLOGFILE",
            "XR_RUNTIME_JSON",
        ]

        def envvar_in_suffixes_to_keep(envvar):
            for env_var in env_var_suffixes_to_keep:
                if envvar.endswith(env_var):
                    return True
            return False

        env_vars = os.environ
        env_vars.update(extra_env_vars)
        for envvar, value in env_vars.items():
            var_tokens = envvar.split("_")
            if var_tokens[0] in env_var_prefixes_to_keep or envvar in env_vars_to_keep or envvar_in_suffixes_to_keep(envvar) or (not os.environ.get('GST_BUILD_PATH') and var_tokens[0] == "GST"):
                sandbox_environment[envvar] = value

        remote_sccache_configs = set(["SCCACHE_REDIS", "SCCACHE_BUCKET", "SCCACHE_MEMCACHED",
                                      "SCCACHE_GCS_BUCKET", "SCCACHE_AZURE_CONNECTION_STRING",
                                      "WEBKIT_USE_SCCACHE"])
        if remote_sccache_configs.intersection(set(os.environ.keys())) and start_sccache and not building_local_deps:
            _log.debug("Enabling network access for the remote sccache")
            flatpak_command.append(share_network_option)

            sccache_environment = {}
            if os.path.isfile(self.sccache_config_file) and not self.regenerate_toolchains and \
               "SCCACHE_CONF" not in os.environ.keys():
                sccache_environment["SCCACHE_CONF"] = convert_webkit_source_path_to_sandbox_path(self.sccache_config_file)

            override_sccache_server_port = os.environ.get("WEBKIT_SCCACHE_SERVER_PORT")
            if override_sccache_server_port:
                _log.debug("Overriding sccache server port to %s" % override_sccache_server_port)
                sccache_environment["SCCACHE_SERVER_PORT"] = override_sccache_server_port

            if building:
                # Spawn the sccache server in background, and avoid recursing here, using a bool keyword.
                _log.debug("Pre-starting the SCCache dist server")
                self.run_in_sandbox("sccache", "--start-server", env=sccache_environment, building_local_deps=building_local_deps,
                                    extra_flatpak_args=[share_network_option], start_sccache=False)

            # Forward sccache server env vars to sccache clients.
            sandbox_environment.update(sccache_environment)

        if self.use_icecream and not skip_icc:
            _log.debug('Enabling the icecream compiler')
            flatpak_command.extend([share_network_option, "--filesystem=home"])

            try:
                n_cores = os.environ["NUMBER_OF_PROCESSORS"]
            except KeyError:
                n_cores = multiprocessing.cpu_count() * 3
                _log.debug('Following icecream recommendation for the number of cores to use: %d' % n_cores)
            toolchain_name = os.environ.get("CC", "gcc")
            default_toolchain = self.icc_version.get(toolchain_name)

            try:
                toolchain_override = os.environ["ICECC_VERSION_OVERRIDE"]
            except KeyError:
                toolchain_path = default_toolchain
            else:
                if not os.path.isfile(toolchain_override):
                    Console.error_message("%s toolchain not found. ICECC_VERSION_OVERRIDE mis-configured?", toolchain_override)
                    return 1

                toolchain_path = convert_webkit_source_path_to_sandbox_path(toolchain_override)

            if not toolchain_path:
                Console.error_message("Toolchains configuration not found. Please run webkit-flatpak -r or set ICECC_VERSION_OVERRIDE to a valid host path")
                return 1

            if "ICECC_VERSION_APPEND" in os.environ:
                extra_toolchain = os.environ["ICECC_VERSION_APPEND"]
                if not os.path.isfile(extra_toolchain):
                    Console.error_message("%s is not a valid IceCC toolchain. ICECC_VERSION_APPEND mis-configured?", extra_toolchain)
                    return 1
                toolchain_path += ","
                toolchain_path += convert_webkit_source_path_to_sandbox_path(extra_toolchain)

            sandbox_environment.update({
                "CCACHE_PREFIX": "icecc",
                "ICECC_TEST_SOCKET": "/run/icecc/iceccd.socket",
                "ICECC_VERSION": toolchain_path,
                "NUMBER_OF_PROCESSORS": n_cores,
            })

        # Set PKG_CONFIG_PATH in sandbox so uninstalled WebKit.pc files can be used.
        pkg_config_path = os.environ.get("PKG_CONFIG_PATH")
        if pkg_config_path:
            pkg_config_path = "%s:%s" % (self.build_path, pkg_config_path)
        else:
            pkg_config_path = self.build_path
        sandbox_environment["PKG_CONFIG_PATH"] = pkg_config_path

        if not building_local_deps and args[0] != "sccache":
            # Merge local dependencies build env vars in sandbox environment, without overriding
            # previously set PATH values.
            local_env = self.setup_local_deps(building)
            sandbox_environment = self._merge_env_variables(sandbox_environment, local_env)

        for envvar, value in sandbox_environment.items():
            flatpak_command.append("--env=%s=%s" % (envvar, value))

        # $WEBKIT_OUTPUTDIR is not forwarded in the build sandbox because the host build path is
        # always bind-mounted to /app in the sandbox.
        env_vars_to_drop = ("WEBKIT_OUTPUTDIR", "LANGUAGE")
        flatpak_env = os.environ.copy()
        for envvar in list(flatpak_env.keys()):
            if envvar.startswith("LC_") or envvar in env_vars_to_drop:
                del flatpak_env[envvar]
                if self.flatpak_version >= (1, 10, 0):
                    flatpak_command.append("--unset-env=%s" % envvar)

        # Avoid 'error: Invalid byte sequence in conversion input' after removing
        # all `LANG` vars.
        flatpak_env["LANG"] = "en_US.UTF-8"

        keep_signals = args[0] != "gdb"
        if not keep_signals:
            module_path = os.path.join(self.build_path, "lib", "libsigaction-disabler.so")
            # Enable module in bwrap child processes.
            extra_flatpak_args.append("--env=WEBKIT_FLATPAK_LD_PRELOAD=%s" % module_path)
            # Enable module in `flatpak run`.
            flatpak_env["LD_PRELOAD"] = module_path

        flatpak_command += extra_flatpak_args + ['--command=%s' % args[0], "org.webkit.Sdk"] + args[1:]

        flatpak_env.update({
            "FLATPAK_BWRAP": os.path.join(SCRIPT_DIR, "webkit-bwrap"),
            "WEBKIT_BUILD_DIR_BIND_MOUNT": "%s:%s" % (sandbox_build_path, self.build_path),
            "WEBKIT_FLATPAK_USER_DIR": os.environ["FLATPAK_USER_DIR"],
        })

        display = os.environ.get("DISPLAY")
        if display:
            flatpak_env["WEBKIT_FLATPAK_DISPLAY"] = display

        # FIXME: Remove duplicate values from the flatpak command.
        command = flatpak_command

        if gather_output:
            return run_sanitized(command, gather_output=True, ignore_stderr=False, env=flatpak_env)

        try:
            return self.execute_command(command, stdout=stdout, env=flatpak_env, keep_signals=keep_signals)
        except KeyboardInterrupt:
            return 0

        return 0

    def main(self):
        if self.check_available:
            return 0

        if not self.clean_args():
            return 1

        if self.show_version:
            print(self.sdk_repo.version("org.webkit.Sdk"))
            return 0

        if self.update:
            flatpak_wrapper = FlatpakObject(True)
            version_before_update = flatpak_wrapper.version("org.webkit.Sdk")
            flatpak_wrapper.flatpak_update()
            regenerate_toolchains = (flatpak_wrapper.version("org.webkit.Sdk") != version_before_update) or not self.check_toolchains_generated()

            # If we have an out-of-date package, simply remove the entire flatpak directory and start over.
            for package in self._get_dependency_packages():
                if package.name.startswith("org.webkit") \
                   and self.repos.is_package_installed(package.name) \
                   and not self.repos.is_package_installed(package.name, branch=SDK_BRANCH):

                    # Cache sccache auth token before removing UserFlatpak.
                    self.acquire_sccache_auth_token_from_config_file()

                    Console.message("New SDK version available, removing local UserFlatpak directory before switching to new version")
                    shutil.rmtree(self.flatpak_build_path)

                    Console.message("Forcing next WebKit build to re-run CMake")
                    for platform in ('GTK', 'WPE'):
                        for build_type in ('Release', 'Debug'):
                            cache_path = os.path.join(get_build_dir(platform, build_type), 'CMakeCache.txt')
                            if os.path.isfile(cache_path):
                                Console.message("Removing %s", cache_path)
                                os.remove(cache_path)

                    self._reset_repository()
                    break

            for package in self._get_dependency_packages():
                if not self.repos.is_package_installed(package.name):
                    package.install()
                    regenerate_toolchains = True

            print("SDK version: {}".format(self.sdk_repo.version("org.webkit.Sdk")))

        else:
            regenerate_toolchains = self.regenerate_toolchains

        result = self.setup_dev_env()
        if regenerate_toolchains:

            # Toolchains used to be stored in WebKitBuild/Toolchains. Remove this path if found, to save
            # up disk space.
            old_toolchains_path = os.path.join(DEFAULT_BUILD_ROOT, "Toolchains")
            if os.path.isdir(old_toolchains_path):
                Console.message("Purging obsolete toolchains")
                shutil.rmtree(old_toolchains_path)

            if not os.path.isdir(self.toolchains_directory):
                os.makedirs(self.toolchains_directory)

            Console.message("Updating icecc/sccache standalone toolchain archives")
            self.icc_version = {}
            gcc_archive, toolchains = self.pack_toolchain(("gcc", "g++"), {"/usr/bin/c++": "g++",
                                                                           "/usr/bin/cc": "gcc"})
            clang_archive, clang_toolchains = self.pack_toolchain(("clang", "clang++"), {"/usr/bin/clang++": "clang++",
                                                                                          "/usr/bin/clang": "clang"})
            toolchains.extend(clang_toolchains)
            if len(toolchains) > 1:
                self.save_config(toolchains)
                self.purge_unused_toolchains((gcc_archive, clang_archive))
            else:
                Console.error_message("Error generating icecc/sccache standalone toolchain archives")

        return result

    def run(self):
        try:
            return self.main()
        except subprocess.CalledProcessError as error:
            Console.error_message("The following command returned a non-zero exit status: %s\n"
                                  "Output: %s", ' '.join(error.cmd), error.output)
            return error.returncode
        return 0

    def has_environment(self):
        return os.path.exists(self.flatpak_build_path)

    def acquire_sccache_auth_token_from_config_file(self):
        if os.path.isfile(self.sccache_config_file) and not self.sccache_token:
            Console.message("Reusing sccache auth token from old configuration file")
            with open(self.sccache_config_file) as config:
                sccache_config = toml.load(config)
                self.sccache_token = sccache_config['dist']['auth']['token']

    def save_config(self, toolchains):
        with open(self.config_file, 'w') as config:
            json_config = {'icecc_version': self.icc_version}
            json.dump(json_config, config)

        self.acquire_sccache_auth_token_from_config_file()

        if not self.sccache_token:
            Console.message("No authentication token provided. Re-run this with the -t option if an sccache token was provided to you. Skipping sccache configuration for now.")
            return

        with open(self.sccache_config_file, 'w') as config:
            sccache_config = {'dist': {'scheduler_url': self.sccache_scheduler,
                                       'auth': {'type': 'token',
                                                'token': self.sccache_token},
                                       'toolchains': toolchains}}
            toml.dump(sccache_config, config)
            Console.message("Created %s sccache config file. It will automatically be used when building WebKit", self.sccache_config_file)

    def purge_unused_toolchains(self, allow_list):
        for filename in os.listdir(self.toolchains_directory):
            if filename not in allow_list:
                _log.debug("Removing unused toolchain: %s", filename)
                os.remove(os.path.join(self.toolchains_directory, filename))

    def check_toolchains_generated(self):
        found_toolchains = 0
        if os.path.isfile(self.config_file):
            with open(self.config_file, 'r') as config_fd:
                config = json.load(config_fd)
                if 'icecc_version' in config:
                    for compiler in config['icecc_version']:
                        if os.path.isfile(convert_sandbox_path_to_webkit_source_path(config['icecc_version'][compiler])):
                            found_toolchains += 1
        return found_toolchains > 1

    def pack_toolchain(self, compilers, path_mapping):
        compiler_mapping = {}
        for compiler in compilers:
            compiler_mapping[compiler] = self.run_in_sandbox("/usr/bin/which", compiler, gather_output=True)

        with tempfile.NamedTemporaryFile() as tmpfile:
            command = ['icecc', '--build-native']
            command.extend(compiler_mapping.values())
            retcode = self.run_in_sandbox(*command, stdout=tmpfile, cwd=WEBKIT_SOURCE_DIR, skip_icc=True)
            if retcode != 0:
                Console.error_message('Flatpak command "%s" failed with return code %s', " ".join(command), retcode)
                return []
            tmpfile.flush()
            tmpfile.seek(0)
            icc_version_filename, = re.findall(br'.*creating (.*)', tmpfile.read())
            relative_filename = "webkit-sdk-{name}-{filename}".format(name=compilers[0], filename=icc_version_filename.decode())
            archive_filename = os.path.join(self.toolchains_directory, relative_filename)
            os.rename(icc_version_filename, archive_filename)
            archive_sandbox_path = convert_webkit_source_path_to_sandbox_path(archive_filename)
            self.icc_version[compilers[0]] = archive_sandbox_path
            Console.message("Created %s self-contained toolchain archive", archive_filename)

            sccache_toolchains = []
            for (compiler_executable, archive_compiler_executable) in path_mapping.items():
                item = {'type': 'path_override',
                        'compiler_executable': compiler_executable,
                        'archive': archive_sandbox_path,
                        'archive_compiler_executable': compiler_mapping[archive_compiler_executable]}
                sccache_toolchains.append(item)
            return (relative_filename, sccache_toolchains)

    def check_installed_packages(self):
        for package in self._get_dependency_packages():
            if package.name.startswith("org.webkit") and not package.is_installed(SDK_BRANCH):
                Console.error_message("Flatpak package %s not installed. Please update your SDK: Tools/Scripts/update-webkit-flatpak", package)
                return False
        else:
            return True


    def setup_dev_env(self):
        if not os.path.exists(os.path.join(self.flatpak_build_path, "runtime", "org.webkit.Sdk")) or self.update:
            self.install_all()

        if not self.update and not self.check_installed_packages():
            return 1

        if self.gdb or self.gdb_stack_trace:
            return self.run_gdb()
        elif self.user_command:
            program = self.user_command[0]
            if self.is_build_webkit(program) and self.cmakeargs:
                self.user_command.append("--cmakeargs=%s" % self.cmakeargs)

            return self.run_in_sandbox(*self.user_command + self.extra_command_args)
        elif not self.update and not self.build_local_deps and not self.regenerate_toolchains:
            return self.run_in_sandbox()

        return 0

    def _get_dependency_packages(self):
        arch = platform.machine()
        self.runtime = FlatpakPackage("org.webkit.Platform", SDK_BRANCH,
                                      self.sdk_repo, arch)
        self.sdk = FlatpakPackage("org.webkit.Sdk", SDK_BRANCH,
                                  self.sdk_repo, arch)
        packages = [self.runtime, self.sdk]
        packages.append(FlatpakPackage('org.webkit.Sdk.Debug', SDK_BRANCH,
                                       self.sdk_repo, arch))
        packages.append(FlatpakPackage("org.freedesktop.Sdk.Extension.llvm13", SDK_BRANCH,
                                       self.flathub_repo, arch))
        packages.append(FlatpakPackage("org.freedesktop.Platform.GL.default", SDK_BRANCH,
                                       self.flathub_repo, arch))
        return packages

    def install_all(self):
        if os.path.exists(os.path.join(self.flatpak_build_path, "runtime", "org.webkit.Sdk")):
            return
        Console.message("Installing %s dependencies in %s", self.build_type, self.flatpak_build_path)
        for package in self._get_dependency_packages():
            if not package.is_installed(SDK_BRANCH):
                package.install()

    def run_gdb(self):
        with disable_signals():
            try:
                subprocess.check_output(['which', 'coredumpctl'])
            except subprocess.CalledProcessError as e:
                Console.message("'coredumpctl' not present on the system, can't run. (%s)\n", e)
                return e.returncode

        # We need access to the host from the sandbox to run.
        with tempfile.NamedTemporaryFile() as coredump:
            with tempfile.NamedTemporaryFile() as stderr:
                if self.gdb_stack_trace:
                    cmd = ["coredumpctl", "--since=%s" % self.gdb_stack_trace, "dump"]
                else:
                    cmd = ["coredumpctl", "dump"] + shlex.split(self.coredumpctl_matches)

                result = self.execute_command(cmd, stdout=coredump, stderr=stderr)
                if result != 0:
                    Console.error_message("coredumpctl failed")
                    with open(stderr.name, 'r') as stderrf:
                        stderr = stderrf.read()
                        Console.error_message(stderr)
                    return result

                with open(stderr.name, 'r') as stderrf:
                    stderr = stderrf.read()

                executable, = re.findall(".*Executable: (.*)", stderr)

                if self.gdb:
                    bargs = ["gdb", executable, "/run/host/%s" % coredump.name]
                    if type(self.gdb) != bool:
                        bargs.extend(shlex.split(self.gdb))
                elif self.gdb_stack_trace:
                    bargs = ["gdb", '-ex', "thread apply all backtrace", '--batch', executable, "/run/host/%s" % coredump.name]

                return self.run_in_sandbox(*bargs)

def is_sandboxed():
    return os.path.exists("/.flatpak-info")


def run_in_sandbox_if_available(args):
    if os.environ.get('WEBKIT_JHBUILD', '0') == '1':
        return None

    os.environ["FLATPAK_USER_DIR"] = os.environ.get("WEBKIT_FLATPAK_USER_DIR", FLATPAK_USER_DIR_PATH)
    if not os.path.isdir(os.environ["FLATPAK_USER_DIR"]):
        return None

    if is_sandboxed():
        return None

    if not check_flatpak(verbose=False):
        return None

    # Filter out flatpakutils args for the app.
    runner_args = []
    app_args = []
    opt_prefix = "--flatpak-"
    for arg in args:
        if arg.startswith(opt_prefix):
            runner_args.append("--%s" % arg[len(opt_prefix):])
        else:
            runner_args.append(arg)
            app_args.append(arg)

    flatpak_runner = WebkitFlatpak.load_from_args(runner_args, add_help=False)
    if not flatpak_runner.clean_args():
        return None

    if not flatpak_runner.has_environment():
        return None

    sys.exit(flatpak_runner.run_in_sandbox(*app_args))
