# -*- 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 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

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"

scriptdir = os.path.abspath(os.path.dirname(__file__))
_log = logging.getLogger(__name__)

FLATPAK_USER_DIR_PATH = os.path.realpath(os.path.join(scriptdir, "../../WebKitBuild", "UserFlatpak"))
DEFAULT_SCCACHE_SCHEDULER='https://sccache.igalia.com'

# 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"

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):
    """ 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 = dict(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
        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


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)
        ignore_stderr = kwargs.get("ignore_stderr", 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)

        _log.debug("Executing %s" % ' '.join(command))
        return run_sanitized(command, gather_output=gather_output, ignore_stderr=ignore_stderr)

    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 ""

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

    def update(self):
        if not self.is_installed(self.branch):
            return self.install()

        comment = "Updating %s" % self.name
        self.flatpak("update", self.name, self.branch, comment=comment)


@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)


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("-bgst", "--build-gst", dest="build_gst",
                             action="store_true",
                             help="Force rebuilding gst-build, repository path is defined by the `GST_BUILD_PATH` environment variable.")
        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\")")

        _, self.args = parser.parse_known_args(args=args, namespace=self)

        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.source_root = os.path.normpath(os.path.abspath(os.path.join(scriptdir, '../../')))
        # Where the source folder is mounted inside the sandbox.
        self.sandbox_source_root = "/app/webkit"

        self.base_build_dir = 'WebKitBuild'

        self.build_gst = 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

        # 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.
        self.default_build_root = os.path.join(self.source_root, self.base_build_dir)

        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')

        build_root = os.environ.get("WEBKIT_OUTPUTDIR", self.source_root)
        self.build_root = os.path.join(build_root, self.base_build_dir)
        self.build_path = os.path.join(self.build_root, 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 = "https://software.igalia.com/webkit-sdk-repo/"
        repo_file = "https://software.igalia.com/flatpak-refs/webkit-sdk.flatpakrepo"
        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_gstbuild(self, building):
        gst_dir = os.environ.get('GST_BUILD_PATH')
        if not gst_dir:
            if building:
                _log.debug("$GST_BUILD_PATH environment variable not set. Skipping gst-build\n")
            return {}

        if not os.path.exists(os.path.join(gst_dir, 'gst-env.py')):
            raise RuntimeError('GST_BUILD_PATH set to %s but it doesn\'t seem to be a valid `gst-build` checkout.' % gst_dir)

        gst_builddir = os.path.join(self.source_root, self.base_build_dir, 'gst-build')
        if not os.path.exists(os.path.join(self.default_build_root, 'gst-build', 'build.ninja')):
            if not building:
                raise RuntimeError('Trying to enter gst-build env from %s but it is not built, make sure to rebuild webkit.' % gst_dir)

            args = ['meson', ]
            extra_args = os.environ.get('GST_BUILD_ARGS', '')
            args.extend(shlex.split(extra_args) + [gst_dir, gst_builddir])
            Console.message("Running %s ", ' '.join(args))
            self.run_in_sandbox(*args, building_gst=True, start_sccache=False)

        if building:
            Console.message("Building `gst-build` %s ", gst_dir)
            if self.run_in_sandbox('ninja', '-C', gst_builddir, building_gst=True, start_sccache=False) != 0:
                raise RuntimeError('Error while building gst-build.')

        command = [os.path.join(gst_dir, 'gst-env.py'), '--builddir', gst_builddir, '--srcdir', gst_dir, "--only-environment"]
        gst_env = run_sanitized(command, gather_output=True)
        allowlist = ("LD_LIBRARY_PATH", "PATH", "PKG_CONFIG_PATH")
        nopathlist = ("GST_DEBUG", "GST_VERSION", "GST_ENV")
        env = {}
        for line in [line for line in gst_env.splitlines() if not line.startswith("export")]:
            tokens = line.split("=")
            var_name, contents = tokens[0], "=".join(tokens[1:])
            if not var_name.startswith("GST_") and var_name not in allowlist:
                continue
            if var_name not in nopathlist:
                new_contents = ':'.join([self.host_path_to_sandbox_path(p) for p in contents.split(":")])
            else:
                new_contents = contents.replace("'", "")
            env[var_name] = new_contents
        return env

    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 host_path_to_sandbox_path(self, host_path):
        # For now this supports only files in the WebKit path
        return host_path.replace(self.source_root, self.sandbox_source_root)

    def run_in_sandbox(self, *args, **kwargs):
        if not self.setup_builddir():
            return 1
        cwd = kwargs.get("cwd", None)
        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_gst = kwargs.get("building_gst", False)
        gather_output = kwargs.get("gather_output", False)

        if gather_output:
            start_sccache = False
            skip_icc = True
            building_gst = False

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

        sandbox_build_path = os.path.join(self.sandbox_source_root, self.base_build_dir, self.build_type)
        sandbox_environment = {
            "TEST_RUNNER_INJECTED_BUNDLE_FILENAME": os.path.join(sandbox_build_path, "lib/libTestRunnerInjectedBundle.so"),
            "PATH": "/usr/lib/sdk/llvm12/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] = command.replace(self.source_root, self.sandbox_source_root)

            if args[0] == "bash":
                args.extend(['--noprofile', '--norc', '-i'])
                sandbox_environment["PS1"] = "[📦🌐🐱 $FLATPAK_ID \\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.a11y.Bus",
                           "--talk-name=org.gtk.vfs",
                           "--talk-name=org.gtk.vfs.*"]

        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": "PST8PDT",
            })

        env_var_prefixes_to_keep = [
            "G",
            "CCACHE",
            "EGL",
            "GIGACAGE",
            "GTK",
            "ICECC",
            "JSC",
            "MESA",
            "LIBGL",
            "PIPEWIRE",
            "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_gst:
            _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"] = self.host_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_gst=building_gst,
                                    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 = self.host_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 += self.host_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_gst and args[0] != "sccache":
            # Merge gst-build env vars in sandbox environment, without overriding previously set PATH values.
            gst_env = self.setup_gstbuild(building)
            for var_name in list(gst_env.keys()):
                if var_name not in sandbox_environment:
                    sandbox_environment[var_name] = gst_env[var_name]
                else:
                    contents = gst_env[var_name]
                    if var_name.endswith('PATH'):
                        sandbox_environment[var_name] = "%s:%s" % (sandbox_environment[var_name], contents)

        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(scriptdir, "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=True, 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:
            repo = self.sdk_repo
            version_before_update = repo.version("org.webkit.Sdk")
            repo.flatpak("update", comment="Updating Flatpak %s environment" % self.build_type)
            regenerate_toolchains = (repo.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(self.build_root, 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

        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(self.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(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=self.source_root, 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 = self.host_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)
        elif not self.update and not self.build_gst 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.llvm12", 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))
