#!/usr/bin/env sh
#
# Copyright (C) 2025 Igalia S.L.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
set -eu

SCRIPTPATH="$(realpath -- "${0}")"
SCRIPTDIR="$(dirname -- "${SCRIPTPATH}")"
WEBKITDIR="$(realpath -- "${SCRIPTDIR}/../..")"
WEBKIT_SOURCE_DIR="${WEBKIT_SOURCE_DIR:-${WEBKITDIR}}"
WEBKIT_SOURCE_DIR="$(realpath -m -- "${WEBKIT_SOURCE_DIR}")"

help() {
    cat <<EOF
Usage: ${0} program-to-execute [arguments...]
       ${0} --create-symlink

This script is used by the WebKit tooling when running inside the
webkit-container-sdk for GTK/WPE port development. It enables building
WebKit and running tests inside a common path at /sdk/webkit.

Options:
    -h, --help         Show this help message
    --create-symlink   Create /sdk/webkit as a symlink to ${WEBKIT_SOURCE_DIR}
                       and exit. Useful for tools not executed through this
                       wrapper (like gdb) that need to resolve /sdk/webkit paths.

Default behavior:
    Creates a private mount namespace where /sdk/webkit is a bind-mount
    to ${WEBKIT_SOURCE_DIR}, then executes the specified program.

Examples:
    ${0} Tools/Scripts/build-webkit --wpe --release
    ${0} --create-symlink
EOF
    exit 0
}

error() {
    printf '%s\n' "${@}" 1>&2
    exit 1
}

# If path starts with ${WEBKIT_SOURCE_DIR}, replace that prefix with /sdk/webkit.
maybe_replace_path_prefix_to_rootsdk() {
    case "${1}" in
        "${WEBKIT_SOURCE_DIR}"|"${WEBKIT_SOURCE_DIR}"/*)
            printf '%s\n' "/sdk/webkit${1#"${WEBKIT_SOURCE_DIR}"}"
        ;;
        *)
            printf '%s\n' "${1}"
        ;;
    esac
}

resolve_relpath_to_abs_if_outside() {
    abs=$(realpath -m -- "${ORGPWD}/${1}")
    case "${abs}" in
        "${WEBKIT_SOURCE_DIR}"|"${WEBKIT_SOURCE_DIR}"/*)
            # Inside the tree: keep original relative value
            printf '%s\n' "${1}"
        ;;
        *) # relative path outside the tree: make it absolute
            printf '%s\n' "${abs}"
        ;;
    esac
}

maybe_update_relpath_to_abs_if_outside() {
    case "${1}" in
        ""|/*|*://*)
            # do not touch if is empty or looks like an abs path or a URL
            printf '%s\n' "${1}"
        ;;
        .|..|./*|../*|*/*)
            resolve_relpath_to_abs_if_outside "${1}"
        ;;
        *)
            if [ -L "${1}" ]; then
                resolve_relpath_to_abs_if_outside "${1}"
            else
                printf '%s\n' "${1}"
            fi
        ;;
    esac
}

# Convert relative paths to absolute if they point outside ${WEBKIT_SOURCE_DIR}
args_maybe_update_outside_relpaths() {
    for arg in "${@}"; do
        case "${arg}" in
            --*=*)  # handle arguments like "--option=value"
                key="${arg%%=*}"
                val="${arg#*=}"
                val="$(maybe_update_relpath_to_abs_if_outside "${val}")"
                arg="${key}=${val}"
                ;;
            *)
                arg="$(maybe_update_relpath_to_abs_if_outside "${arg}")"
                ;;
        esac
        printf "'"
        printf '%s' "${arg}" | sed "s/'/'\\\\''/g"
        printf "' "
    done
}

[ "$#" -ge 1 ] || help
[ "${1}" = "--help" ] && help
[ "${1}" = "-h" ] && help

[ -d "${WEBKIT_SOURCE_DIR}" ] || error "Can't find directory: ${WEBKIT_SOURCE_DIR}"
[ -d /sdk ] || error "Can't find /sdk directory"
[ -w /sdk ] || error "Directory /sdk is not writable for user $(whoami)"

case "${WEBKIT_SOURCE_DIR}" in
  /sdk|/sdk/*) error "${0} should not be invoked with WEBKIT_SOURCE_DIR under /sdk directory" ;;
esac

if [ "${1}" = "--create-symlink" ]; then
    [ "$#" -ge 2 ] && error "No extra arguments can be passed with --create-symlink"
    if [ -L "/sdk/webkit" ]; then
        CURSYMLINKDEST="$(realpath -m -- /sdk/webkit)"
        if [ "${CURSYMLINKDEST}" != "${WEBKIT_SOURCE_DIR}" ]; then
            rm -f "/sdk/webkit"
            ln -s "${WEBKIT_SOURCE_DIR}" "/sdk/webkit"
            echo "Symlink at /sdk/webkit changed from ${CURSYMLINKDEST} to ${WEBKIT_SOURCE_DIR}"
        fi
    elif ! [ -e "/sdk/webkit" ]; then
        ln -s "${WEBKIT_SOURCE_DIR}" "/sdk/webkit"
    else
        error "ERROR: /sdk/webkit exists and is not a symlink. This is unexpected"
    fi
    exit 0
fi

CURUID="$(id -u)"
CURGID="$(id -g)"
ORGPWD="$(pwd)"
SDKPWD="$(maybe_replace_path_prefix_to_rootsdk "${ORGPWD}")"
# Try also with the realpath, just in case pwd is inside a symlinked dir.
if [ "${ORGPWD}" = "${SDKPWD}" ]; then
    ORGPWD="$(realpath -- "${ORGPWD}")"
    SDKPWD="$(maybe_replace_path_prefix_to_rootsdk "${ORGPWD}")"
fi
# When $(pwd) is inside ${WEBKIT_SOURCE_DIR}, switch (cd) to the equivalent bind-mount path
# under /sdk/webkit. Any relative path arguments that point outside ${WEBKIT_SOURCE_DIR} are
# converted to absolute paths first, since they wouldn't resolve correctly after the switch.
[ "${ORGPWD}" != "${SDKPWD}" ] && eval "set -- $(args_maybe_update_outside_relpaths "${@}")"

# Since util-linux 2.27 is not needed to execute mount --make-rprivate /
# because unshare does that automatically by default for new mount namespaces
exec unshare -rm sh -c '
    set -eu
    WEBKIT_SOURCE_DIR="${1}"
    SDKPWD="${2}"
    CURUID="${3}"
    CURGID="${4}"
    shift 4
    mount -t tmpfs -o size=16M tmpfs /sdk
    mkdir /sdk/webkit
    mount --bind "${WEBKIT_SOURCE_DIR}" /sdk/webkit
    cd "${SDKPWD}"
    export WEBKIT_CONTAINER_SDK_INSIDE_MOUNT_NAMESPACE=1
    exec unshare --map-user="${CURUID}" --map-group="${CURGID}" -- "${@}"
' -- "${WEBKIT_SOURCE_DIR}" "${SDKPWD}" "${CURUID}" "${CURGID}" "${@}"
