#!/bin/sh
# Example App uninstaller — macOS and Linux.
#
# Generated by ariza from App::ExampleApp's ariza.toml. Do not edit this
# file: edit ariza's resources/templates/uninstall-posix.sh.j2 and re-run
# `ariza installers --app=<this repository>`.
#
#   curl -fsSL https://raw.githubusercontent.com/example-org/App-ExampleApp/HEAD/uninstall.sh | sh
#   sh uninstall.sh
#
# Removes exactly what install.sh created: the versions directory, the
# `current` symlink, the ~/.local/bin link, and the marked PATH block in
# your shell rc files. Anything Example App itself wrote — your data,
# your configuration — is left alone, and this says where it is rather
# than deciding for you.

set -eu

APP_DISPLAY='Example App'
APP_EXEC='exampleapp'

ARIZA_PATH_MARKER="# >>> $APP_EXEC PATH >>>"
ARIZA_PATH_END="# <<< $APP_EXEC PATH <<<"

ARIZA_ROOT="${XDG_DATA_HOME:-$HOME/.local/share}/$APP_EXEC"
ARIZA_BIN_DIR="$HOME/.local/bin"
ARIZA_STATE="${XDG_STATE_HOME:-$HOME/.local/state}/$APP_EXEC"

############################# common runtime ##################################
###############################################################################
# ariza installer runtime (POSIX)
#
# Inlined verbatim into install.sh and uninstall.sh at render time, so a
# generated installer is one self-contained file with nothing to source
# and nothing to download before it can start.
#
# Adapted from the pre-bundle installers' template/lib/common-posix.sh --
# the registry, the package-manager probes and the terminal detection are
# gone (a bundle installs none of that), the PATH marker machinery is
# kept, because getting it wrong duplicates blocks in people's rc files.
#
# Callers must have set: APP_DISPLAY, APP_EXEC, ARIZA_PATH_MARKER,
# ARIZA_PATH_END.
###############################################################################

# Colour only when someone is watching. `curl … | sh` in a CI log is not.
if [ -t 1 ]; then
    ariza_c_blue='\033[34m'; ariza_c_green='\033[32m'; ariza_c_red='\033[31m'
    ariza_c_yellow='\033[33m'; ariza_c_reset='\033[0m'
else
    ariza_c_blue=''; ariza_c_green=''; ariza_c_red=''
    ariza_c_yellow=''; ariza_c_reset=''
fi

ariza_log()  { printf "${ariza_c_blue}==>${ariza_c_reset} %s\n" "$*"; }
ariza_ok()   { printf "${ariza_c_green}ok${ariza_c_reset}  %s\n" "$*"; }
ariza_warn() { printf "${ariza_c_yellow}!!${ariza_c_reset}  %s\n" "$*" >&2; }
ariza_err()  { printf "${ariza_c_red}error${ariza_c_reset} %s\n" "$*" >&2; exit 1; }

ariza_have() { command -v "$1" >/dev/null 2>&1; }

# ---- downloading -------------------------------------------------------------

ariza_download() {
    # $1 = url, $2 = destination. Fails on any HTTP error rather than
    # writing a 404 page to disk and calling it an archive.
    if ariza_have curl; then
        curl --fail --location --silent --show-error --retry 3 -o "$2" "$1"
    elif ariza_have wget; then
        wget --quiet --tries=3 -O "$2" "$1"
    else
        ariza_err "need curl or wget to download $1"
    fi
}

# ---- checksums ---------------------------------------------------------------

ariza_sha256() {
    # $1 = file. Echoes the lowercase hex digest, or returns 1 if this
    # machine has no tool that can compute one.
    if ariza_have sha256sum; then
        sha256sum "$1" | cut -d' ' -f1
    elif ariza_have shasum; then
        shasum -a 256 "$1" | cut -d' ' -f1
    else
        return 1
    fi
}

ariza_first_word() {
    # $1 = a `<hex>  <filename>` checksum file, as shasum -c reads.
    awk 'NR == 1 { print $1; exit }' "$1"
}

ariza_verify_sha256() {
    # $1 = file, $2 = expected hex. Fatal on any disagreement.
    _actual=$(ariza_sha256 "$1" || true)
    [ -n "$_actual" ] || ariza_err "no sha256sum or shasum on this machine, so the download cannot be verified"
    if [ "$_actual" != "$2" ]; then
        ariza_err "checksum mismatch for $(basename "$1"): expected $2, got $_actual -- not installing"
    fi
}

# ---- shell rc PATH wiring ----------------------------------------------------
#
# One marker block, named after the executable rather than after the
# project, so uninstalling one app never removes the line another app is
# relying on. Re-running never duplicates it: the marker is grepped for
# first, and the whole block is skipped when the directory is already on
# PATH, which is the common case on a second install.

ariza_persist_path() {
    # $1 = directory to put on PATH.
    #
    # Records whether the directory was on PATH BEFORE this function
    # touched anything, in ARIZA_PATH_WAS_PRESENT. The parting message
    # keys on that record, not on $PATH: this function's last act is to
    # export the directory into this script's own PATH, so a check made
    # after it runs always says "present" and the tell-the-user branch
    # becomes unreachable — which is exactly how the first real install
    # ended with a command the user's terminal could not find and no
    # line telling them why.
    _dir=$1
    case ":${PATH:-}:" in
        *":$_dir:"*)
            # Already there for this shell, so a login shell almost
            # certainly has it too. Adding a block would be one more
            # thing to clean up later for no gain.
            ARIZA_PATH_WAS_PRESENT=1
            return 0
            ;;
    esac
    ARIZA_PATH_WAS_PRESENT=0

    _block=$(printf '%s\ncase ":$PATH:" in\n  *":%s:"*) ;;\n  *) PATH="%s:$PATH"; export PATH ;;\nesac\n%s\n' \
        "$ARIZA_PATH_MARKER" "$_dir" "$_dir" "$ARIZA_PATH_END")

    _rc_seen=0
    for _rc in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.profile"; do
        [ -f "$_rc" ] || continue
        _rc_seen=$((_rc_seen + 1))
        grep -Fq "$ARIZA_PATH_MARKER" "$_rc" 2>/dev/null && continue
        # An unterminated last line would otherwise swallow the marker,
        # and a decorative blank line before the block would survive the
        # uninstaller — accumulating one per install/uninstall cycle.
        [ -n "$(tail -c 1 "$_rc")" ] && printf '\n' >>"$_rc"
        printf '%s\n' "$_block" >>"$_rc"
        ariza_ok "added $_dir to PATH in $_rc"
    done

    if [ "$_rc_seen" -eq 0 ]; then
        ariza_warn "no shell rc file found -- add this to yours by hand:"
        printf '        export PATH="%s:$PATH"\n' "$_dir" >&2
    fi

    PATH="$_dir:$PATH"
    export PATH
}

ariza_unpersist_path() {
    # Remove our own marker block, and only ours, from every rc file that
    # has one. Rewritten through the existing file rather than moved over
    # it, so the rc file keeps its mode and ownership.
    for _rc in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.profile"; do
        [ -f "$_rc" ] || continue
        grep -Fq "$ARIZA_PATH_MARKER" "$_rc" 2>/dev/null || continue
        _tmp=$(mktemp "${TMPDIR:-/tmp}/ariza-rc.XXXXXX")
        awk -v m="$ARIZA_PATH_MARKER" -v em="$ARIZA_PATH_END" '
            $0 == m  { skip = 1; next }
            $0 == em { skip = 0; next }
            !skip    { print }
        ' "$_rc" >"$_tmp"
        cat "$_tmp" >"$_rc"
        rm -f "$_tmp"
        ariza_ok "removed the PATH block from $_rc"
    done
}

###############################################################################

ariza_usage() {
    cat <<USAGE
Usage: uninstall.sh [-h|--help]

Removes $ARIZA_ROOT, the $ARIZA_BIN_DIR/$APP_EXEC link, and the
$APP_EXEC PATH block from your shell rc files. Nothing else is touched.
USAGE
}

ariza_remove_bin_link() {
    _bin="$ARIZA_BIN_DIR/$APP_EXEC"
    if [ -L "$_bin" ]; then
        # Only ours. Someone may have their own $APP_EXEC on PATH, and a
        # tool that deletes a link it did not create is a tool nobody
        # runs twice.
        _target=$(readlink "$_bin" || true)
        case $_target in
            "$ARIZA_ROOT"/*)
                rm -f "$_bin"
                ariza_ok "removed $_bin"
                ;;
            *)
                ariza_warn "$_bin points at $_target, which is not ours -- leaving it alone"
                ;;
        esac
    elif [ -e "$_bin" ]; then
        ariza_warn "$_bin is not a symlink -- leaving it alone"
    fi
}

main() {
    case ${1:-} in
        -h|--help) ariza_usage; exit 0 ;;
        '') ;;
        *) ariza_err "unknown option '$1' -- run with --help" ;;
    esac

    ariza_log "uninstalling $APP_DISPLAY"

    if [ -d "$ARIZA_ROOT" ]; then
        rm -rf "$ARIZA_ROOT"
        ariza_ok "removed $ARIZA_ROOT"
    else
        ariza_log "nothing installed at $ARIZA_ROOT"
    fi

    ariza_remove_bin_link
    ariza_unpersist_path

    printf '\n'
    ariza_ok "$APP_DISPLAY uninstalled"
    printf '    Not touched, because this installer never wrote them:\n'
    printf '      %s\n' "$ARIZA_STATE"
    printf '      any data or configuration %s created for you\n' "$APP_DISPLAY"
}

main "$@"
