#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2020 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 os
import itertools
import shlex
import stat
import sys
import tempfile
import json

scriptdir = os.path.abspath(os.path.dirname(__file__))

def read_lines(fd: int):
    new_fd = os.dup(fd)
    pos = os.lseek(fd, 0, os.SEEK_CUR)
    try:
        with os.fdopen(new_fd, 'r') as handle:
            data = handle.read()
            lines = data.split('\x00')
            for line in lines:
                yield line
    except Exception as e:
        print("Error reading brwap arguments", file=sys.stderr)
        print(e, file=sys.stderr)
    finally:
        os.lseek(fd, pos, os.SEEK_SET)



def main(args: list) -> int:
    tmpdir = tempfile.gettempdir()
    source_root = os.path.normpath(os.path.abspath(os.path.join(scriptdir, '../../')))
    build_root = os.path.join(source_root, 'WebKitBuild')
    bind_mounts = {
        "/app/webkit":  source_root,
        # Access to /run/host is required by the crash log reporter.
        f"/run/host{tmpdir}": f"{tmpdir}",
        "/run/shm": "/dev/shm",
    }

    args_idx = args.index('--args')
    arg_fd = int(args[args_idx + 1])

    lines = read_lines(arg_fd)

    environ = os.environ.copy()
    while True:
        try:
            arg = next(lines)
            if arg == '--setenv':
                key = next(lines)
                value = next(lines)
                environ[key] = value
        except StopIteration:
            break

    flatpak_user_dir = environ.get("WEBKIT_FLATPAK_USER_DIR")
    if flatpak_user_dir:
        bind_mounts["/var/tmp"] = os.path.join(flatpak_user_dir, "var", "tmp")

    try_bind_mounts = {
        "/run/icecc": "/var/run/icecc"
    }

    build_path = environ.get("WEBKIT_BUILD_DIR_BIND_MOUNT")
    if build_path:
        dest, src = build_path.split(":")
        try_bind_mounts[dest] = src

    coredumps_dir = environ.get("WEBKIT_CORE_DUMPS_DIRECTORY")
    if coredumps_dir:
        try_bind_mounts[coredumps_dir] = coredumps_dir

    bwrap_args = ["bwrap", ]

    xdg_runtime_dir = environ.get("XDG_RUNTIME_DIR")
    if xdg_runtime_dir:
        pipewire_runtime_dir = "/host/xdg-runtime"
        bwrap_args.extend(("--ro-bind-try", xdg_runtime_dir, pipewire_runtime_dir,
                           "--setenv", "PIPEWIRE_RUNTIME_DIR", pipewire_runtime_dir))

    for dst, src in bind_mounts.items():
        bwrap_args.extend(("--bind", src, dst))

    for dst, src in try_bind_mounts.items():
        bwrap_args.extend(("--bind-try", src, dst))

    display = environ.get("WEBKIT_FLATPAK_DISPLAY")
    if display:
        bwrap_args.extend(("--setenv", "DISPLAY", display))

    for env in environ.keys():
        if env.startswith("LC_") or env == "LANGUAGE":
            bwrap_args.extend(("--unsetenv", env))

    if environ.get("WEBKIT_FLATPAK_LD_PRELOAD"):
        os.environ["LD_PRELOAD"] = environ["WEBKIT_FLATPAK_LD_PRELOAD"]

    command_line = ' '.join(map(shlex.quote, itertools.chain(bwrap_args, args)))

    # os.system return code behaves like os.wait. A 16 bit number with the
    # signal in the lower byte and, if the signal is zero, the exit code in
    # the high byte.
    return os.system(command_line) >> 8

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
