# 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=/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("/.flatpak-info")


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