#!/usr/bin/sh

# wm-launch - launch X11 clients with unique IDs
# Copyright (C) 2019-2020 James Reed

# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <https://www.gnu.org/licenses/>.

set -eu

readonly LIBPREFIX=/usr/lib
readonly VERSION=v0.5.1

readonly PRELOAD="${WM_LAUNCH_PRELOAD:-$LIBPREFIX/wm-launch/wm-launch-preload.so}"
readonly WORKSPACE_FILENAME="${WM_LAUNCH_WORKSPACE_FILENAME:-.workspace}"

readonly SYSTEMD_RUN='systemd-run --user --scope'

readonly DBUS_NAME='com.github.jcrd.wm_launch'
readonly DBUS_METHOD="$DBUS_NAME.WindowManager.NewWorkspace"
readonly DBUS_PATH='/com/github/jcrd/wm_launch/WindowManager'

usage() {
    echo 'usage: wm-launch [options] WM_LAUNCH_ID COMMAND...

options:
  -h          Show help message
  -s          Launch with systemd-run
  -j          Launch with firejail
  -f FACTORY  Launch via a window factory
  -w DIR      Launch workspace from DIR
  -v          Show version'
}

usage_error() {
    usage >&2
    exit 2
}

new_workspace() {
    path="$(realpath "$1/$WORKSPACE_FILENAME")"

    if [ ! -f "$path" ]; then
        echo "$path is not a workspace file" >&2
        exit 2
    fi

    dir="${path%/*}"
    clients=""

    while read -r line; do
        clients="$clients,'$line'"
    done < "$path"

    gdbus call -e -d $DBUS_NAME -o $DBUS_PATH -m $DBUS_METHOD \
        "${dir##*/}" "$dir" "[${clients#,}]" > /dev/null
}

while getopts ':hsjf:w:v' opt; do
    case "$opt" in
        h) usage; exit ;;
        s) systemd=true ;;
        j) firejail=true ;;
        f) factory="$OPTARG" ;;
        w) new_workspace "$OPTARG"; exit ;;
        v) echo "$VERSION"; exit ;;
        *) usage_error
    esac
done

shift $((OPTIND - 1))

if [ -z "$DISPLAY" ]; then
    echo 'DISPLAY not set' >&2
    exit 1
fi

[ $# -lt 2 ] && usage_error

launch_id="$1"
shift

launch_env="WM_LAUNCH_ID=$launch_id"

if [ -n "${factory+x}" ]; then
    if [ -n "$factory" ]; then
        if wm-launchd -factory "$factory"; then
            launch_env=""
        else
            launch_env="WM_LAUNCH_FACTORY=$factory"
        fi
        wm-launchd -factory "$factory" -id "$launch_id"
    else
        launch_env="WM_LAUNCH_FACTORY= $launch_env"
    fi
fi

if [ -n "${firejail-}" ]; then
    exec ${systemd+$SYSTEMD_RUN} firejail \
        ${launch_env+--env=LD_PRELOAD="$PRELOAD" --env="$launch_env"} "$@"
fi

exec ${launch_env+env LD_PRELOAD="$PRELOAD" $launch_env} \
    ${systemd+$SYSTEMD_RUN} "$@"
