#!/bin/sh
# NanoPing installer.
#
#   curl -sS https://get.nanoping.com | sh
#
# Set NANOPING_INSTALL_DIR to install somewhere other than /usr/local/bin.
set -eu

APP_NAME="NanoPing"
BIN_NAME="np"
VERSION="10.6.0"
BASE_URL="https://get.nanoping.com"
INSTALL_DIR="${NANOPING_INSTALL_DIR:-/usr/local/bin}"
# Where the binary keeps its state by default; np --app-data overrides it.
APP_DATA_DIR="${HOME:-~}/nanoping"
DOCS_URL="https://docs.nanoping.com"

fail() {
    echo "$APP_NAME installer: $1" >&2
    exit 1
}

step() {
    echo "✓ $1"
}

command -v curl >/dev/null 2>&1 || fail "curl is required"

os=$(uname -s 2>/dev/null || echo unknown)
arch=$(uname -m 2>/dev/null || echo unknown)

case "$os" in
    Linux) os=linux ;;
    Darwin) os=macos ;;
    MINGW*|MSYS*|CYGWIN*|Windows_NT) os=windows ;;
    *) fail "unsupported operating system: $os" ;;
esac

case "$arch" in
    x86_64|amd64) arch=x86_64 ;;
    arm64|aarch64|armv7l|armv8l) arch=arm ;;
    *) fail "unsupported architecture: $arch" ;;
esac

echo "Installing latest version of $BIN_NAME ($APP_NAME $VERSION) …"

tmp=$(mktemp -d 2>/dev/null || mktemp -d -t nanoping)
trap 'rm -rf "$tmp"' EXIT INT TERM

(cd "$tmp" && curl -fsSL -O -J "$BASE_URL/latest/$os/$arch") ||
    fail "no $VERSION download available for $os/$arch"

asset=$(ls "$tmp" | head -n 1)
[ -n "$asset" ] || fail "download failed"
step "finished downloading"

unpack_dir="$tmp/unpacked"
mkdir -p "$unpack_dir"
case "$asset" in
    *.tar.gz|*.tgz)
        command -v tar >/dev/null 2>&1 || fail "tar is required to unpack $asset"
        tar -xzf "$tmp/$asset" -C "$unpack_dir"
        ;;
    *.zip)
        command -v unzip >/dev/null 2>&1 || fail "unzip is required to unpack $asset"
        unzip -q "$tmp/$asset" -d "$unpack_dir"
        ;;
    *)
        mv "$tmp/$asset" "$unpack_dir/$BIN_NAME"
        chmod +x "$unpack_dir/$BIN_NAME"
        ;;
esac

# The command sits in the archive root under its own name, which is the name it is documented and
# supported under, so keep it. An extensionless file wins over a sibling script.
binary=$(find "$unpack_dir" -maxdepth 1 -type f -name "$BIN_NAME" | head -n 1)
if [ -z "$binary" ]; then
    binary=$(find "$unpack_dir" -maxdepth 1 -type f -perm -u+x ! -name '*.*' | sort | head -n 1)
fi
if [ -z "$binary" ]; then
    binary=$(find "$unpack_dir" -maxdepth 1 -type f -perm -u+x | sort | head -n 1)
fi
if [ -z "$binary" ]; then
    # Archives that wrap everything in a single top-level directory.
    binary=$(find "$unpack_dir" -maxdepth 2 -type f -perm -u+x | sort | head -n 1)
fi
[ -n "$binary" ] || fail "no executable found in $asset"

command_name=$(basename "$binary")
chmod +x "$binary"

if [ -w "$INSTALL_DIR" ]; then
    mv "$binary" "$INSTALL_DIR/$command_name"
elif command -v sudo >/dev/null 2>&1; then
    sudo mv "$binary" "$INSTALL_DIR/$command_name"
    sudo chmod +x "$INSTALL_DIR/$command_name"
else
    fail "$INSTALL_DIR is not writable and sudo is unavailable: set NANOPING_INSTALL_DIR to a writable directory"
fi

step "installed $command_name to $INSTALL_DIR/$command_name"
step "configuration storage defaults to $APP_DATA_DIR (override with --app-data)"
echo ""
echo "Go to $DOCS_URL for documentation."
echo ""
echo "Now run \"sudo $command_name up\" to start $APP_NAME as a daemon"
