#! /usr/bin/env bash

this_dir="$(readlink -f "$(dirname "$0")")"
if [ -f "${APPDIR}/GnuPG-VS-Desktop-VERSION" ]; then
    _gnupg_appimage=vsd
    _gnupg_appimage_name="GnuPG VS-Desktop"
    myname="$_gnupg_appimage_name "$(cat "${APPDIR}/GnuPG-VS-Desktop-VERSION")
elif [ -f "${APPDIR}/GnuPG-Desktop-VERSION" ]; then
    _gnupg_appimage=desktop
    _gnupg_appimage_name="GnuPG Desktop"
    myname="$_gnupg_appimage_name "$(cat "${APPDIR}/GnuPG-Desktop-VERSION")
else
    _gnupg_appimage=generic
    _gnupg_appimage_name="Gpg4win"
    myname="$_gnupg_appimage_name "$(cat "${APPDIR}/Gpg4win-VERSION")
fi

opt_c=no
opt_gui=no
opt_keep_socket=no
opt_debug=no
opt_version=no
lastoption=no
while [ $# -gt 0 ]; do
    case "$1" in
        --)
            lastoption=yes
            ;;
        -c|-i)
            opt_c=yes
            lastoption=yes
            ;;
	--gui)
	    opt_gui=yes
	    ;;
	--keep-socket)
	    opt_keep_socket=yes
	    ;;
	--debug)
	    opt_debug=yes
	    ;;
        --version)
            opt_version=yes
            cat <<EOF
$myname
Copyright (C) 2022 g10 Code GmbH

${_gnupg_appimage_name} consists of several independent developed packages,
available under different license conditions.  Most of these packages
however are available under the GNU General Public License (GNU GPL).
Common to all is that they are free to use without restrictions, may
be modified and that modifications may be distributed.

If the source code is distributed along with the binaries and the
use of the GNU GPL has been pointed out, distribution is in in all
cases possible.

The list of used licenses and their text is part of the source code
and also available online at <https://gnupg.com/vsd/licenses.html>.

"GnuPG Desktop" and "GnuPG VS-Desktop" are registered trademarks of
g10 Code GmbH.  For more infomation see <https://gnupg.com>.

EOF
            ;;
	--help|-h)

            cat <<EOF
$myname

Options:
  -c            Run an interactive shell.
  -c command    Run command with optional arguments.
  --gui         Run the GUI with optional arguments.
  --keep-socket Keep an existing gpg-agent socket.
  --debug       Enable debugging of the start script.
  --version     Print version and copyright info
  --help        Print this help.

The default is to run the GUI with optional arguments.

EOF
	    exit 0
	    ;;
	*)
	    break
	    ;;
    esac
    shift
    if [ $lastoption = yes ]; then
        break;
    fi
done

if [ $opt_debug = yes ]; then
    set -x
else
    set -e
fi


if [ $opt_version = yes ]; then
    # Do some basic verification - not really secure because an
    # attacker may change the appimage and the included keyring.
    if [ ! -f "$APPIMAGE".sig ]; then
        echo "error: no signature found for this appimage" >&2
        exit 2
    elif ! "${APPDIR}"/usr/bin/gpgv --quiet \
         --keyring "${APPDIR}"/usr/share/gnupg/distsigkey.gpg \
         "$APPIMAGE".sig "$APPIMAGE" ; then
        echo "error: this appimage is not correctly signed" >&2
        exit 2
    fi
    exit 0
fi

export PATH="${APPDIR}/usr/bin:${PATH}"
export XDG_DATA_DIRS="${APPDIR}/usr/share:${XDG_DATA_DIRS:-/usr/share}:/usr/share"
export XDG_CONFIG_DIRS="${APPDIR}/usr/etc/xdg:${XDG_CONFIG_DIRS:-/etc/xdg}:/etc/xdg"
export MANPATH="${APPDIR}/usr/share/man:${MANPATH:-/usr/share/man}:/usr/share/man"
export QT_PLUGIN_PATH="${APPDIR}/usr/plugins:${APPDIR}/usr/lib/plugins:"

# Avoid problems due to caller set ld.so envvars.
if [ -n "$LD_PRELOAD" ]; then
  _gnupg_save_LD_PRELOAD="$LD_PRELOAD"
  LD_PRELOAD=
fi
if [ -n "$LD_LIBRARY_PATH" ]; then
  _gnupg_save_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
  LD_LIBRARY_PATH=
fi

# Allow GnuPG config scripts to detect the appimage install.  We can't
# rely on APPDIR because other appimages might come with their own
# gnupg version.  Change the value to "vsd" for a GnuPG VS-Desktop build.
if [ ${_gnupg_appimage} = vsd ]; then
   prestart_snippet=/etc/gnupg-vsd/apprun.pre-start.sh
else
   prestart_snippet=/etc/gnupg/apprun.pre-start.sh
fi
export _gnupg_appimage

if [ -z "$SHELL" ]; then
    SHELL="$(grep '/bash$' /etc/shells 2>/dev/null)"
    if [ -z "$SHELL" ]; then
        export SHELL=/bin/bash
    fi
fi



mycleanup () {
    if [ -n $"gnupg_SETUPINIFILE" ]; then
        rm -f $"gnupg_SETUPINIFILE"
    fi
}

gnupg_SETUPINIFILE=
trap mycleanup 0 INT QUIT

callerargs=no
if [ $opt_c = yes ]; then
    if [ ! -x "$SHELL" ]; then
        echo "error: no shell found" >&2
        exit 2
    fi
    if [ -n "$1" ]; then
        pgm=/usr/bin/env
        pgmargs=
        callerargs=yes
    else
        export gnupg_SETUPINIFILE SHELL
        if [ ${_gnupg_appimage} = vsd ]; then
          if [ $(id -u) -eq 0 ]; then
            dotcfg="/etc/gnupg-vsd/.config-by-appimage"
            docopy=yes
            if [ ! -d /etc/gnupg-vsd ]; then
                echo "no global configuration - installing default" >&2
                mkdir /etc/gnupg-vsd
            elif [ -f $dotcfg \
                   -a "$(head -1 $dotcfg 2>/dev/null)" = "$myname" ]; then
                docopy=no
            else
                echo "updating global configuration" >&2
            fi
            if [ $docopy = yes ]; then
              for f in "${APPDIR}"/usr/share/gnupg/conf/gnupg-vsd/* ; do
                t="/etc/gnupg-vsd/${f##*/}"
                if [ -d "$f" ]; then
                    cp -R "$f" /etc/gnupg-vsd/
                elif [ -f "$t" ]; then
                    cp "$t" "$t.old"
                    cp "$f" "$t"
                    cmp -s "$t" "$t.old" && rm "$t.old"
                else
                    cp "$f" "$t"
                fi
              done
              echo "$myname" >$dotcfg
            fi
          fi
        fi
        if echo "$SHELL" | grep '/bash$' >/dev/null 2>&1; then
            pgm="${APPDIR}/start-shell"
            pgmargs=
            gnupg_SETUPINIFILE="/tmp/gnupg-tmp.$(id -u).$$.ini"
        else
            pgm="$SHELL"
            pgmargs="-i"
        fi
        echo Welcome to "$myname"\! >&2
        echo "(type \"exit\" to leave)" >&2
        echo "" >&2
    fi
else
    if [ $(id -u) -eq 0 ]; then
        echo "error: the GUI may not be run by root" >&2
        exit 2
    fi
    if [ -x "${this_dir}/usr/bin/kleopatra" ];then
        pgm="${this_dir}/usr/bin/kleopatra"
        pgmargs=
        callerargs=yes
    else
        echo "Kleopatra not found" >&2
        exit 2
    fi
fi

# The admin may tweak this script by creating a snippet to be sourced
# here.  For example, this can be used to set a different per user
# GNUPGHOME so that the entire installation will be separate from the
# system's standard configuration.
if [ -f $prestart_snippet ]; then
     echo "note: including $prestart_snippet" >&2
    . $prestart_snippet
fi

# In vsd mode create a .gnupg-vsd so that we use a dedicated homedir
# for VSD.  This is important on Linux because there gpg is a
# standard tool and a .gnupg is often in active use.
if [ ${_gnupg_appimage} = vsd -a -z "$GNUPGHOME" ]; then
    GNUPGHOME="$HOME/.gnupg-vsd"
    export GNUPGHOME
    if [ ! -d "$GNUPGHOME" ]; then
        mkdir "$GNUPGHOME"
        chmod 700 "$GNUPGHOME"
    fi
    # Create a script so that external programs have a way to figure
    # out information on this AppImage instance.  We don't fail on
    # write error so that it is usable also in read-only environments.
    cat > "$GNUPGHOME"/run-gpgconf <<EOF || true
#!/bin/sh
# Created by $myname
GNUPGHOME="$GNUPGHOME"
APPDIR="$APPDIR"
export GNUPGHOME APPDIR
exec $APPDIR/usr/bin/gpgconf "\$@"
EOF
    chmod +x "$GNUPGHOME"/run-gpgconf || true
elif [ ${_gnupg_appimage} = desktop -a -w "${GNUPGHOME:-$HOME/.gnupg}" ]; then
    # Create a script so that external programs have a way to figure
    # out information on this AppImage instance.  We don't fail on
    # write error so that it is usable also in read-only environments.
    cat > "${GNUPGHOME:-$HOME/.gnupg}"/run-desktop-gpgconf <<EOF || true
#!/bin/sh
# Created by $myname
GNUPGHOME="${GNUPGHOME:-$HOME/.gnupg}"
APPDIR="$APPDIR"
export GNUPGHOME APPDIR
exec $APPDIR/usr/bin/gpgconf "\$@"
EOF
    chmod +x "${GNUPGHOME:-$HOME/.gnupg}"/run-desktop-gpgconf || true
fi

# Start gpg-agent launching a program.  gpg-agent will then watch for
# termination of the program and kill itself after this has been
# detected.  We also steal an existing socket so that already running
# system instances of gpg-agent are not anymore used.
if [ $opt_keep_socket = yes ]; then
   "${this_dir}/usr/bin/gpgconf" --launch gpg-agent
    if [ $callerargs = yes ]; then
        $pgm $pgmargs "$@"
    else
        $pgm $pgmargs
    fi
else
    if [ $callerargs = yes ]; then
        "${this_dir}/usr/bin/gpg-agent" --steal-socket --daemon \
                                        -- $pgm $pgmargs "$@"
    else
        "${this_dir}/usr/bin/gpg-agent" --steal-socket --daemon \
                                        -- $pgm $pgmargs
    fi
fi

echo Goodbye from "$myname"\! >&2
