#!/usr/bin/env bash
#
# Nobody Agent Installer (self-extracting)
#
# Installs nobody-agent on a managed host.
# Run again to update. Configs and tokens are never overwritten.
#

set -euo pipefail

# When piped from curl, $0 is "bash" and we can't seek back into the script
# to extract the archive. Save to a temp file and re-exec.
if [[ ! -f "$0" ]]; then
    SELF="$(mktemp /tmp/nobody-install.XXXXXX)"
    cat > "$SELF"
    bash "$SELF" "$@"
    STATUS=$?
    rm -f "$SELF"
    exit $STATUS
fi

INSTALL_VERSION="v0.0.0-274"
OS="$(uname -s)"

# --- Help ---
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
    echo "Nobody Agent Installer ${INSTALL_VERSION}"
    echo
    echo "Usage: bash install-agent.sh [options]"
    echo
    echo "Options:"
    echo "  --uninstall      Remove Nobody agent binary and services"
    echo "  --help           Show this help"
    exit 0
fi

# --- Parse arguments ---
UNINSTALL=false
while [[ $# -gt 0 ]]; do
    case "$1" in
        --uninstall) UNINSTALL=true; shift ;;
        *)           echo "Unknown option: $1 (try --help)"; exit 1 ;;
    esac
done

# --- System-wide install paths ---
BIN_DIR="/usr/local/bin"
CONFIG_DIR="/etc/nobody"

# --- Uninstall ---
if [[ "$UNINSTALL" == true ]]; then
    echo "Uninstalling Nobody agent..."

    if [[ "$OS" == "Linux" ]] && command -v systemctl &>/dev/null; then
        systemctl stop nobody-agent 2>/dev/null || true
        systemctl disable nobody-agent 2>/dev/null || true
        rm -f /etc/systemd/system/nobody-agent.service
        systemctl daemon-reload 2>/dev/null || true
        echo "  Removed systemd service"
    fi

    if [[ "$OS" == "Darwin" ]]; then
        if [[ -f /Library/LaunchDaemons/dev.nobody.agent.plist ]]; then
            launchctl unload /Library/LaunchDaemons/dev.nobody.agent.plist 2>/dev/null || true
            rm -f /Library/LaunchDaemons/dev.nobody.agent.plist
            echo "  Removed LaunchDaemon"
        fi
    fi

    if [[ -f "${BIN_DIR}/nobody-agent" ]]; then
        rm -f "${BIN_DIR}/nobody-agent"
        echo "  Removed ${BIN_DIR}/nobody-agent"
    fi

    echo
    echo "Nobody agent uninstalled."
    echo "Config and token files were NOT removed."
    exit 0
fi

# --- Install ---
INSTALLED="none"
if command -v nobody-agent &>/dev/null; then
    INSTALLED="$(nobody-agent --version 2>/dev/null | head -1 || echo "unknown")"
fi

if [[ "$INSTALLED" == "none" ]]; then
    echo "Installing Nobody Agent ${INSTALL_VERSION}..."
else
    echo "Updating Nobody Agent (${INSTALLED} -> ${INSTALL_VERSION})..."
fi
echo

# --- Extract embedded payload ---
TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT

ARCHIVE_START=$(awk '/^__ARCHIVE__$/{print NR + 1; exit 0;}' "$0")
tail -n +"${ARCHIVE_START}" "$0" | base64 -d | tar xz -C "${TMPDIR}"

# --- Stop service if running ---
AGENT_WAS_RUNNING=false
if [[ "$OS" == "Linux" ]] && command -v systemctl &>/dev/null; then
    if systemctl is-active --quiet nobody-agent 2>/dev/null; then
        echo "  Stopping nobody-agent..."
        systemctl stop nobody-agent
        AGENT_WAS_RUNNING=true
    fi
elif [[ "$OS" == "Darwin" ]]; then
    if launchctl list dev.nobody.agent &>/dev/null; then
        launchctl unload /Library/LaunchDaemons/dev.nobody.agent.plist 2>/dev/null || true
        AGENT_WAS_RUNNING=true
    fi
fi

# --- Install binary ---
mkdir -p "$BIN_DIR"
if [[ -f "${TMPDIR}/nobody-agent" ]]; then
    cp "${TMPDIR}/nobody-agent" "${BIN_DIR}/nobody-agent"
    chmod 0755 "${BIN_DIR}/nobody-agent"
    echo "  ${BIN_DIR}/nobody-agent"
else
    echo "Error: nobody-agent not found in payload"
    exit 1
fi

# --- Install service ---
if [[ "$OS" == "Linux" ]] && command -v systemctl &>/dev/null; then
    if [[ -f "${TMPDIR}/nobody-agent.service" ]]; then
        cp "${TMPDIR}/nobody-agent.service" /etc/systemd/system/nobody-agent.service
        echo "  /etc/systemd/system/nobody-agent.service"
        systemctl daemon-reload
    fi
elif [[ "$OS" == "Darwin" ]]; then
    if [[ -f "${TMPDIR}/dev.nobody.agent.system.plist" ]]; then
        cp "${TMPDIR}/dev.nobody.agent.system.plist" /Library/LaunchDaemons/dev.nobody.agent.plist
        chown root:wheel /Library/LaunchDaemons/dev.nobody.agent.plist
        chmod 644 /Library/LaunchDaemons/dev.nobody.agent.plist
        echo "  /Library/LaunchDaemons/dev.nobody.agent.plist"
    fi
fi

# --- Create directories and generate token ---
mkdir -p "$CONFIG_DIR"
mkdir -p /etc/nobody/tls
chmod 0750 /etc/nobody/tls

GENERATED_TOKEN=""
AGENT_CONFIG="${CONFIG_DIR}/agent.yaml"
if [[ ! -f "$AGENT_CONFIG" ]]; then
    GENERATED_TOKEN=$(head -c 32 /dev/urandom | base64 | tr -d '/+=' | head -c 32)
    cat > "$AGENT_CONFIG" <<YAML
agent:
  token: ${GENERATED_TOKEN}
  listen: ":8443"
YAML
    chmod 0600 "$AGENT_CONFIG"
    echo "  ${AGENT_CONFIG}"
else
    GENERATED_TOKEN=$(grep 'token:' "$AGENT_CONFIG" 2>/dev/null | awk '{print $2}' || true)
fi

# --- Generate persistent TLS certificate ---
if [[ ! -f /etc/nobody/tls/agent.crt ]]; then
    echo "  Generating TLS certificate..."
    ${BIN_DIR}/nobody-agent --generate-cert /etc/nobody/tls
fi

# --- Start the service ---
echo
if [[ "$OS" == "Linux" ]] && command -v systemctl &>/dev/null; then
    if systemctl is-enabled --quiet nobody-agent 2>/dev/null; then
        echo "  Starting nobody-agent..."
        systemctl restart nobody-agent
    else
        echo "  Enabling and starting nobody-agent..."
        systemctl enable --now nobody-agent
    fi
elif [[ "$OS" == "Darwin" ]]; then
    PLIST="/Library/LaunchDaemons/dev.nobody.agent.plist"
    if [[ -f "$PLIST" ]]; then
        echo "  Starting nobody-agent..."
        launchctl load "$PLIST" 2>/dev/null || true
    fi
fi

# Give the agent a moment to start.
sleep 1

# --- Done ---
HOSTNAME=$(hostname -f 2>/dev/null || hostname)

echo
echo "  Nobody Agent ${INSTALL_VERSION} installed"
echo

if [[ -n "${GENERATED_TOKEN:-}" ]]; then
    echo "  Agent token: ${GENERATED_TOKEN}"
    echo
    echo "  To add this host from the Nobody TUI:"
    echo "    /host add ${HOSTNAME} ${HOSTNAME} ${GENERATED_TOKEN}"
    echo
fi

exit 0
__ARCHIVE__
[payload removed: 5966508 characters]
