# 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

from webkitpy.common.system.systemhost import SystemHost
from webkitpy.port.factory import PortFactory
from webkitpy.common.system.logutils import configure_logging

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

FLATPAK_REQ = [
    ("flatpak", "0.10.0"),
    ("flatpak-builder", "0.10.0"),
]

FLATPAK_VERSION = {}

WPE_MANIFEST_MAP = {
    "qt": "org.webkit.WPEQT.yaml",
}

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


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


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

    for app, required_version in FLATPAK_REQ:
        try:
            output = subprocess.check_output([app, "--version"])
        except (subprocess.CalledProcessError, OSError):
            if verbose:
                Console.message("\n%sYou need to install %s >= %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"
                                "    * http://flatpak.org/%s\n", Colors.FAIL,
                                app, required_version, sys.argv[0], Colors.ENDC)
            return False

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

        version = output.decode("utf-8").split(" ")[1].strip("\n")
        current = comparable_version(version)
        FLATPAK_VERSION[app] = current
        if current < comparable_version(required_version):
            Console.message("\n%s%s %s required but %s found."
                            " Please update and try again%s\n", Colors.FAIL,
                            app, required_version, version, Colors.ENDC)
            return False

    return True


def remove_extension_points(array):
    result_args = []
    for arg in array:
        if(not arg.startswith('--extension')):
            result_args.append(arg)
    return result_args


def remove_comments(string):
    pattern = r"(\".*?\"|\'.*?\')|(/\*.*?\*/|//[^\r\n]*$)"
    # first group captures quoted strings (double or single)
    # second group captures comments (//single-line or /* multi-line */)
    regex = re.compile(pattern, re.MULTILINE | re.DOTALL)

    def _replacer(match):
        # if the 2nd group (capturing comments) is not None,
        # it means we have captured a non-quoted (real) comment string.
        if match.group(2) is not None:
            return ""  # so we will return empty to remove the comment
        else:  # otherwise, we will return the 1st group
            return match.group(1)  # captured quoted-string
    return regex.sub(_replacer, string)


def load_manifest(manifest_path, port_name=None, command=None):
    is_yaml = manifest_path.endswith('.yaml')
    with open(manifest_path, "r") as mr:
        contents = mr.read()

        contents = contents % {"COMMAND": command, "PORTNAME": port_name}
        if is_yaml:
            import yaml
            yaml_load = getattr(yaml, "safe_load", yaml.load)
            manifest = yaml_load(contents)
        else:
            contents = remove_comments(contents)
            manifest = json.loads(contents)

    return manifest


def expand_submodules_recurse(modules, manifest_path, port_name, command):
    all_modules = []
    if type(modules) is str:
        submanifest_path = os.path.join(os.path.dirname(manifest_path), modules)
        submanifest = load_manifest(submanifest_path, port_name=port_name, command=command)
        all_modules.extend(expand_submodules_recurse(submanifest, submanifest_path, port_name, command))
        return all_modules

    # The last recurse manifest expand iteration might lead to a single module.
    if not isinstance(modules, list):
        all_modules.append(modules)
        return all_modules

    for module in modules:
        if type(module) is str:
            submanifest_path = os.path.join(os.path.dirname(manifest_path), module)
            submanifest = load_manifest(submanifest_path, port_name=port_name, command=command)
            all_modules.extend(expand_submodules_recurse(submanifest, submanifest_path, port_name, command))
        else:
            all_modules.append(module)

    return all_modules

def expand_manifest(manifest_path, outfile, port_name, source_root, command):
    """Creates the manifest file."""
    try:
        os.remove(outfile)
    except OSError:
        pass

    manifest = load_manifest(manifest_path, port_name=port_name, command=command)
    if not manifest:
        return False

    if "sdk-hash" in manifest:
        del manifest["sdk-hash"]
    if "runtime-hash" in manifest:
        del manifest["runtime-hash"]

    all_modules = []

    overriden_modules = []
    if "WEBKIT_EXTRA_MODULESETS" in os.environ:
        overriden_modules = load_manifest(os.environ["WEBKIT_EXTRA_MODULESETS"])
        if not overriden_modules:
            overriden_modules = []
    for modules in manifest["modules"]:
        modules = expand_submodules_recurse(modules, manifest_path, port_name, command)

        if not isinstance(modules, list):
            modules = [modules]

        for module in modules:
            for overriden_module in overriden_modules:
                if module['name'] == overriden_module['name']:
                    module = overriden_module
                    overriden_modules.remove(module)
                    break

            all_modules.append(module)

    # And add overriden modules right before the webkit port build def.
    for overriden_module in overriden_modules:
        all_modules.insert(-1, overriden_module)

    manifest["modules"] = all_modules
    for module in manifest["modules"]:
        if not module.get("sources"):
            continue

        if module["sources"][0]["type"] == "git":
            if port_name == module["name"]:
                repo = "file://" + source_root
                module["sources"][0]["url"] = repo

        for source in module["sources"]:
            if source["type"] == "patch" or (source["type"] == "file" and source.get('path')):
                source["path"] = os.path.join(os.path.dirname(manifest_path), source["path"])

    with open(outfile, "w") as of:
        of.write(json.dumps(manifest, indent=4))

    return True


class FlatpakObject:

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

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

        command = ["flatpak", command]
        if self.user:
            res = subprocess.check_output(command + ["--help"]).decode("utf-8")
            if "--user" in res:
                command.append("--user")
        command.extend(args)

        if not show_output:
            return subprocess.check_output(command).decode("utf-8")

        return subprocess.check_call(command)


class FlatpakPackages(FlatpakObject):

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

        self.repos = repos

        self.runtimes = self.__detect_runtimes()
        self.apps = self.__detect_apps()
        self.packages = self.runtimes + self.apps


    def __detect_packages(self, *args):
        packs = []
        if FLATPAK_VERSION["flatpak"] < (1, 1, 2):
            out = self.flatpak("list", "-d", *args)
            package_defs = [line for line in out.split("\n") if line]
            for package_def in package_defs:
                splited_packaged_def = package_def.split()
                name, arch, branch = splited_packaged_def[0].split("/")

                # If installed from a file, the package is in no repo
                repo_name = splited_packaged_def[1]
                repo = self.repos.repos.get(repo_name)

                packs.append(FlatpakPackage(name, branch, repo, arch))
        else:
            out = self.flatpak("list", "--columns=application,arch,branch,origin", *args)
            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)

                packs.append(FlatpakPackage(name, branch, repo, arch))

        return packs


    def __detect_runtimes(self):
        return self.__detect_packages("--runtime")

    def __detect_apps(self):
        return self.__detect_packages()

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


class FlatpakRepos(FlatpakObject):

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

    def update(self):
        self.repos = {}
        if FLATPAK_VERSION["flatpak"] < (1, 1, 2):
            out = self.flatpak("remote-list", "-d")
            remotes = [line for line in out.split("\n") if line]
            for repo in remotes:
                for components in [repo.split(" "), repo.split("\t")]:
                    if len(components) == 1:
                        components = repo.split("\t")
                    name = components[0]
                    desc = ""
                    url = None
                    for elem in components[1:]:
                        if not elem:
                            continue
                        parsed_url = urlparse(elem)
                        if parsed_url.scheme:
                            url = elem
                            break

                        if desc:
                            desc += " "
                        desc += elem

                    if url:
                        break

                if not url:
                    Console.message("No valid URI found for: %s", repo)
                    continue

                self.repos[name] = FlatpakRepo(name, url, desc, repos=self)
        else:
            out = self.flatpak("remote-list", "--columns=name,title,url")
            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, url, title, repos=self)

        self.packages = FlatpakPackages(self)

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

        if same_name:
            if override:
                self.flatpak("remote-modify", repo.name, "--url=" + repo.url,
                             comment="Setting repo %s URL from %s to %s"
                             % (repo.name, same_name.url, repo.url))
                same_name.url = repo.url

                return same_name
            else:
                return None
        else:
            self.flatpak("remote-add", repo.name, "--from", repo.repo_file.name,
                         "--if-not-exists",
                         comment="Adding repo %s" % repo.name)

        repo.repos = self
        return repo


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)
            self.url = repo["Flatpak Repo"]["Url"]
        else:
            assert url

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

        assert self.repo_file_name
        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
        self.hash = hash

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

    def is_installed(self, branch):
        if not self.repo:
            # Bundle installed from file
            return True

        self.repo.repos.update()
        for package in self.repo.repos.packages:
            if package.name == self.name and \
                    package.branch == branch and \
                    package.arch == self.arch:
                return True

        return False

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

        args = ["install", self.repo.name, self.name, "--reinstall", self.branch, "--assumeyes"]
        comment = "Installing from " + self.repo.name + " " + self.name + " " + self.arch + " " + self.branch
        self.flatpak(*args, show_output=True, comment=comment)
        if self.hash:
            args = ["update", "--commit", self.hash, self.name]
            comment = "Updating to %s" % self.hash
            self.flatpak(*args, show_output=True, comment=comment)

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

        extra_args = []
        comment = "Updating %s" % self.name
        if self.hash:
            extra_args = ["--commit", self.hash]
            comment += " to %s" % self.hash

        extra_args.append("--assumeyes")

        self.flatpak("update", self.name, self.branch, show_output=True,
                    *extra_args, comment=comment)


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

    for disabled_signal in signals:
        old_signal_handlers.append((disabled_signal, signal.getsignal(disabled_signal)))
        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 message')
        general.add_argument("--debug",
                            help="Compile with Debug configuration, also installs Sdk debug symboles.",
                            action="store_true")
        general.add_argument("--release", help="Compile with Release configuration.", action="store_true")
        general.add_argument('--platform', action='store', help='Platform to use (e.g., "mac-lion")'),
        general.add_argument('--gtk', action='store_const', dest='platform', const='gtk',
                             help='Alias for --platform=gtk')
        general.add_argument('--wpe', action='store_const', dest='platform', const='wpe',
                            help=('Alias for --platform=wpe'))
        general.add_argument("-nf", "--no-flatpak-update", dest="no_flatpak_update",
                            action="store_true",
                            help="Do not update flaptak runtime/sdk")
        general.add_argument("-u", "--update", dest="update",
                            action="store_true",
                            help="Update the runtime/sdk/app and rebuild the development environment if needed")
        general.add_argument("-b", "--build-webkit", dest="build_webkit",
                            action="store_true",
                            help="Force rebuilding the app.")
        general.add_argument("-ba", "--build-all", dest="build_all",
                            action="store_true",
                            help="Force rebuilding the app and its dependencies.")
        general.add_argument("-q", "--quiet", dest="quiet",
                            action="store_true",
                            help="Do not print anything")
        general.add_argument("-t", "--tests", dest="run_tests",
                            nargs=argparse.REMAINDER,
                            help="Run LayoutTests")
        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("--use-icecream", help="Use the distributed icecream (icecc) compiler.", action="store_true")
        general.add_argument("--wpe-extension", action="store", dest="wpe_extension", help="WPE Extension to enable")

        debugoptions = parser.add_argument_group("Debugging")
        debugoptions.add_argument("--gdb", nargs="?", help="Activate gdb, passing extra args to it if wanted.")
        debugoptions.add_argument("-m", "--coredumpctl-matches", default="", help='Arguments to pass to gdb.')

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

        general.add_argument("--clean", dest="clean", action="store_true",
            help="Clean previous builds and restart from scratch")

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

        return self

    def __init__(self):
        self.sdk_repo = None
        self.runtime = None
        self.locale = None
        self.sdk = None
        self.sdk_debug = None
        self.app = None

        self.verbose = False
        self.quiet = False
        self.packs = []
        self.update = False
        self.args = []
        self.finish_args = None

        self.no_flatpak_update = False
        self.release = False
        self.debug = False
        self.clean = False
        self.run_tests = None
        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.build_webkit = False
        self.build_all = False

        self.sdk_branch = None
        self.platform = "gtk"
        self.build_type = "Release"
        self.manifest_path = None
        self.name = None
        self.build_name = None
        self.flatpak_root_path = None
        self.cache_path = None
        self.app_module = None
        self.flatpak_default_args = []
        self.check_available = False
        self.wpe_extension = None

        # Default application to run in the sandbox
        self.command = None
        self.user_command = []

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

        # Extra build options
        self.cmakeargs = ""
        self.makeargs = ""

        self.use_icecream = False
        self.icc_version = None

    def clean_args(self):
        os.environ["FLATPAK_USER_DIR"] = os.environ.get("WEBKIT_FLATPAK_USER_DIR", os.path.realpath(os.path.join(scriptdir, "../../WebKitBuild", "UserFlatpak")))
        try:
            os.makedirs(os.environ["FLATPAK_USER_DIR"])
        except OSError as e:
            pass

        configure_logging(logging.DEBUG if self.verbose else logging.INFO)
        _log.debug("Using flatpak user dir: %s" % os.environ["FLATPAK_USER_DIR"])

        if not self.debug and not self.release:
            factory = PortFactory(SystemHost())
            port = factory.get(self.platform)
            self.debug = port.default_configuration() == "Debug"
        self.build_type = "Debug" if self.debug else "Release"

        self.platform = self.platform.upper()

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

        self.command = "%s %s %s" % (os.path.join(self.sandbox_source_root,
            "Tools/Scripts/run-minibrowser"),
            "--" + self.platform.lower(),
            " --debug" if self.debug else " --release")

        self.name = "org.webkit.%s" % self.platform

        if self.wpe_extension:
            manifest_filename = WPE_MANIFEST_MAP[self.wpe_extension]
        else:
            manifest_filename = "org.webkit.WebKit.yaml"
        self.manifest_path = os.path.abspath(os.path.join(scriptdir, '../flatpak/') + manifest_filename)

        self.build_name = self.name + "-generated"

        build_root = os.path.join(self.source_root, 'WebKitBuild')
        self.flatpak_build_path = os.path.join(build_root, self.platform, "FlatpakTree" + self.build_type)
        self.cache_path = os.path.join(build_root, "FlatpakCache")
        self.build_path = os.path.join(build_root, self.platform, self.build_type)
        try:
            os.makedirs(self.build_path)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise e
        self.config_file = os.path.join(self.build_path, 'webkit_flatpak_config.json')

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

        repos = FlatpakRepos()
        self.sdk_repo = repos.add(
            FlatpakRepo("flathub",
                        url="https://dl.flathub.org/repo/",
                        repo_file="https://dl.flathub.org/repo/flathub.flatpakrepo"))

        manifest = load_manifest(self.manifest_path, port_name=self.name)
        if not manifest:
            return False

        self.app = manifest['app-id']

        self.sdk_branch = manifest["runtime-version"]
        self.finish_args = manifest.get("finish-args", [])
        self.finish_args = remove_extension_points(self.finish_args)
        self.runtime = FlatpakPackage(manifest['runtime'], self.sdk_branch,
                                      self.sdk_repo, "x86_64",
                                      hash=manifest.get("runtime-hash"))
        self.locale = FlatpakPackage(manifest['runtime'] + '.Locale',
                                     self.sdk_branch, self.sdk_repo, "x86_64")
        self.sdk = FlatpakPackage(manifest['sdk'], self.sdk_branch,
                                  self.sdk_repo, "x86_64",
                                  hash=manifest.get("sdk-hash"))
        self.packs = [self.runtime, self.locale, self.sdk]

        if self.debug:
            self.sdk_debug = FlatpakPackage(manifest['sdk'] + '.Debug', self.sdk_branch,
                                      self.sdk_repo, "x86_64")
            self.packs.append(self.sdk_debug)
        self.manifest_generated_path = os.path.join(self.cache_path,
                                                    self.build_name + ".json")
        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 run_in_sandbox(self, *args, **kwargs):
        cwd = kwargs.pop("cwd", None)
        extra_env_vars = kwargs.pop("env", {})
        stdout = kwargs.pop("stdout", sys.stdout)
        extra_flatpak_args = kwargs.pop("extra_flatpak_args", [])

        if not isinstance(args, list):
            args = list(args)
        if args:
            if 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].endswith("build-webkit"):
                args.append("--prefix=/app")

        sandbox_build_path = os.path.join(self.sandbox_source_root, "WebKitBuild", self.build_type)
        with tempfile.NamedTemporaryFile(mode="w") as tmpscript:
            flatpak_command = ["flatpak", "build", "--die-with-parent",
                "--bind-mount=/run/shm=/dev/shm",
                # Workaround for https://webkit.org/b/187384 to have our own perl modules usable inside the sandbox
                # as setting the PERL5LIB envvar won't work inside apache (and for scripts using `perl -T``).
                "--bind-mount=/etc/perl=%s" % os.path.join(self.flatpak_build_path, "files/lib/perl"),
                "--bind-mount=/run/host/%s=%s" % (tempfile.gettempdir(), tempfile.gettempdir()),
                "--bind-mount=%s=%s" % (self.sandbox_source_root, self.source_root),
                "--talk-name=org.a11y.Bus",
                "--talk-name=org.gtk.vfs",
                "--talk-name=org.gtk.vfs.*",
                # We mount WebKitBuild/PORTNAME/BuildType to /app/webkit/WebKitBuild/BuildType
                # so we can build WPE and GTK in a same source tree.
                "--bind-mount=%s=%s" % (sandbox_build_path, self.build_path)]

            forwarded = {
                "WEBKIT_TOP_LEVEL": "/app/",
                "TEST_RUNNER_INJECTED_BUNDLE_FILENAME": "/app/webkit/lib/libTestRunnerInjectedBundle.so",
                "ICECC_VERSION": self.icc_version,
            }

            env_var_prefixes_to_keep = [
                "GST",
                "GTK",
                "G",
                "JSC",
                "WEBKIT",
                "WEBKIT2",
                "WPE",
                "GIGACAGE",
            ]

            env_vars_to_keep = [
                "JavaScriptCoreUseJIT",
                "Malloc",
                "WAYLAND_DISPLAY",
                "WAYLAND_SOCKET",
                "DISPLAY",
                "LANG",
                "NUMBER_OF_PROCESSORS",
                "CCACHE_PREFIX",
                "QML2_IMPORT_PATH",
            ]

            if self.use_icecream:
                _log.debug('Enabling the icecream compiler')
                forwarded["CCACHE_PREFIX"] = "icecc"
                if not os.environ.get('NUMBER_OF_PROCESSORS'):
                    n_cores = multiprocessing.cpu_count() * 3
                    _log.debug('Follow icecream recommendation for the number of cores to use: %d' % n_cores)
                    forwarded["NUMBER_OF_PROCESSORS"] = n_cores

            env_vars = os.environ
            env_vars.update(extra_env_vars)
            for envvar, value in env_vars.items():
                if envvar.split("_")[0] in env_var_prefixes_to_keep or envvar in env_vars_to_keep:
                    forwarded[envvar] = value

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

            flatpak_command += self.finish_args + extra_flatpak_args + [self.flatpak_build_path]

            shell_string = ""
            if args:
                if cwd:
                    shell_string = 'cd "%s" && "%s"' % (cwd, '" "'.join(args))
                else:
                    shell_string = '"%s"' % ('" "'.join(args))
            else:
                shell_string = self.command
                if self.args:
                    shell_string += ' "%s"' % '" "'.join(self.args)

            tmpscript.write(shell_string)
            tmpscript.flush()

            _log.debug('Running in sandbox: "%s" %s\n' % ('" "'.join(flatpak_command), shell_string))
            flatpak_command.extend(['sh', "/run/host/" + tmpscript.name])

            try:
                subprocess.check_call(flatpak_command, stdout=stdout)
            except subprocess.CalledProcessError as e:
                sys.stderr.write(str(e) + "\n")
                return e.returncode
            except KeyboardInterrupt:
                return 0

        return 0

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

        if not self.clean_args():
            return 1

        if self.clean:
            if os.path.exists(self.flatpak_build_path):
                shutil.rmtree(self.flatpak_build_path)
            if os.path.exists(self.build_path):
                shutil.rmtree(self.build_path)

        if self.update:
            Console.message("Updating Flatpak environment for %s (%s)" % (
                self.platform, self.build_type))
            if not self.no_flatpak_update:
                self.update_all()

        return self.setup_dev_env()

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

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

    def setup_ccache(self):
        for compiler in ["c++", "cc", "clang", "clang++", "g++", "gcc"]:
            self.run_in_sandbox("ln", "-s", "../../usr/bin/ccache", compiler, cwd="/app/bin")

    def setup_icecc(self):
        with tempfile.NamedTemporaryFile() as tmpfile:
            self.run_in_sandbox('icecc', '--build-native', stdout=tmpfile, cwd=self.build_path)
            tmpfile.flush()
            tmpfile.seek(0)
            icc_version_filename, = re.findall(r'.*creating (.*)', tmpfile.read())
            self.icc_version = os.path.join(self.build_path, icc_version_filename)

    def setup_dev_env(self):
        if not os.path.exists(os.path.join(self.build_path, self.flatpak_build_path)) \
                or self.update or self.build_all:
            self.install_all()
            Console.message("Building %s and dependencies in %s",
                            self.name, self.flatpak_build_path)

            # Create environment dirs if necessary
            try:
                os.makedirs(os.path.dirname(self.manifest_generated_path))
            except OSError as e:
                if e.errno != errno.EEXIST:
                    raise e
            if not expand_manifest(self.manifest_path, self.manifest_generated_path,
                                   self.name, self.sandbox_source_root, self.command):
                return 1

            builder_args = ["flatpak-builder", "--disable-rofiles-fuse", "--state-dir",
                            self.cache_path, "--ccache", self.flatpak_build_path, "--force-clean",
                            self.manifest_generated_path]
            builder_args.append("--build-only")
            builder_args.append("--stop-at=%s" % self.app)

            subprocess.check_call(builder_args)
            self.setup_ccache()
            self.setup_icecc()
            self.save_config()

        build_type = "--debug" if self.debug else "--release"
        if self.build_webkit:
            builder = [os.path.join(self.sandbox_source_root, 'Tools/Scripts/build-webkit'),
                build_type, '--' + self.platform.lower()]
            if self.makeargs:
                builder.append("--makeargs=%s" % self.makeargs)
            if self.cmakeargs:
                builder.append("--cmakeargs=%s" % self.cmakeargs)
            Console.message("Building webkit")
            res = self.run_in_sandbox(*builder)

            if res:
                return res
        else:
            Console.message("Using %s prefix in %s", self.name, self.flatpak_build_path)

        if self.run_tests is not None:
            test_launcher = [os.path.join(self.sandbox_source_root, 'Tools/Scripts/run-webkit-tests'),
                build_type, '--' + self.platform.lower()] + self.run_tests
            return self.run_in_sandbox(*test_launcher)
        elif self.gdb is not None:
            return self.run_gdb()
        elif self.user_command:
            return self.run_in_sandbox(*self.user_command)
        elif not self.update and not self.build_webkit:
            return self.run_in_sandbox()

        return 0

    def install_all(self):
        for package in self.packs:
            if not package.is_installed(self.sdk_branch):
                package.install()

    def run_gdb(self):
        with disable_signals():
            try:
                subprocess.check_output(['which', 'coredumpctl'])
            except subprocess.CalledProcessError as e:
                sys.stderr.write("'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:
                subprocess.check_call(["coredumpctl", "dump"] + shlex.split(self.coredumpctl_matches),
                                      stdout=coredump, stderr=stderr)

                with open(stderr.name, 'r') as stderrf:
                    stderr = stderrf.read()
                executable, = re.findall(".*Executable: (.*)", stderr)
                if not executable.startswith("/newroot"):
                    sys.stderr.write("Executable %s doesn't seem to be a flatpaked application.\n" % executable)

                executable = executable.replace("/newroot", "")
                args = ["gdb", executable, "/run/host/%s" % coredump.name] + shlex.split(self.gdb)

                return self.run_in_sandbox(*args)

    def update_all(self):
        for m in [self.runtime, self.sdk, self.sdk_debug]:
            if m:
                m.update()


def is_sandboxed():
    return os.path.exists("/usr/manifest.json")


def run_in_sandbox_if_available(args):
    if is_sandboxed():
        return None

    if not check_flatpak(verbose=False):
        return None

    flatpak_runner = WebkitFlatpak.load_from_args(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(*args))
