#!/usr/bin/env bash
set -euo pipefail

# Bootstrap a dedicated SSH user for pi/assistant administration.
# Intended to be run as root on a Debian/Ubuntu/TurnKey Linux VM.
#
# Examples:
#   ASSISTANT_PUBLIC_KEY='ssh-ed25519 AAAA... comment' bash bootstrap-assistant-ssh-user.sh
#   bash bootstrap-assistant-ssh-user.sh --user piagent --key-file /tmp/piagent.pub
#   bash bootstrap-assistant-ssh-user.sh --user piagent --key 'ssh-ed25519 AAAA...' --passwordless-sudo

USERNAME="piagent"
KEY_FILE=""
PUBLIC_KEY="${ASSISTANT_PUBLIC_KEY:-}"
PASSWORDLESS_SUDO="false"
SHELL_PATH="/bin/bash"

usage() {
  cat <<'EOF'
Usage: bootstrap-assistant-ssh-user.sh [options]

Options:
  --user USER              Username to create/update. Default: piagent
  --key PUBLIC_KEY         SSH public key string to install
  --key-file PATH          File containing SSH public key to install
  --passwordless-sudo      Allow passwordless sudo for this user
  --shell PATH             Login shell. Default: /bin/bash
  -h, --help               Show help

Environment:
  ASSISTANT_PUBLIC_KEY     SSH public key string, used if --key/--key-file omitted

Recommended:
  1. Generate key on your trusted workstation/container:
       ssh-keygen -t ed25519 -f ~/.ssh/piagent_nextcloud -C piagent-nextcloud
  2. Copy the .pub key text into ASSISTANT_PUBLIC_KEY or --key.
EOF
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --user)
      USERNAME="${2:?--user requires a value}"
      shift 2
      ;;
    --key)
      PUBLIC_KEY="${2:?--key requires a value}"
      shift 2
      ;;
    --key-file)
      KEY_FILE="${2:?--key-file requires a value}"
      shift 2
      ;;
    --passwordless-sudo)
      PASSWORDLESS_SUDO="true"
      shift
      ;;
    --shell)
      SHELL_PATH="${2:?--shell requires a value}"
      shift 2
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "Unknown option: $1" >&2
      usage >&2
      exit 2
      ;;
  esac
 done

if [[ "$(id -u)" -ne 0 ]]; then
  echo "ERROR: run as root, or with sudo" >&2
  exit 1
fi

if [[ -n "$KEY_FILE" ]]; then
  if [[ ! -r "$KEY_FILE" ]]; then
    echo "ERROR: key file not readable: $KEY_FILE" >&2
    exit 1
  fi
  PUBLIC_KEY="$(tr -d '\r\n' < "$KEY_FILE")"
fi

if [[ -z "$PUBLIC_KEY" ]]; then
  echo "ERROR: no public key provided. Use --key, --key-file, or ASSISTANT_PUBLIC_KEY." >&2
  exit 1
fi

if ! grep -Eq '^(ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp(256|384|521)) ' <<< "$PUBLIC_KEY"; then
  echo "ERROR: provided key does not look like a supported SSH public key" >&2
  exit 1
fi

if ! [[ "$USERNAME" =~ ^[a-z_][a-z0-9_-]*[$]?$ ]]; then
  echo "ERROR: invalid username: $USERNAME" >&2
  exit 1
fi

if [[ ! -x "$SHELL_PATH" ]]; then
  echo "ERROR: shell does not exist or is not executable: $SHELL_PATH" >&2
  exit 1
fi

if id "$USERNAME" >/dev/null 2>&1; then
  echo "User exists: $USERNAME"
  usermod --shell "$SHELL_PATH" "$USERNAME"
else
  echo "Creating user: $USERNAME"
  useradd --create-home --shell "$SHELL_PATH" --comment "Pi assistant administration user" "$USERNAME"
fi

# Lock password to enforce key-only login for this account.
passwd -l "$USERNAME" >/dev/null || true

HOME_DIR="$(getent passwd "$USERNAME" | cut -d: -f6)"
SSH_DIR="$HOME_DIR/.ssh"
AUTHORIZED_KEYS="$SSH_DIR/authorized_keys"

install -d -m 700 -o "$USERNAME" -g "$USERNAME" "$SSH_DIR"
touch "$AUTHORIZED_KEYS"
chown "$USERNAME:$USERNAME" "$AUTHORIZED_KEYS"
chmod 600 "$AUTHORIZED_KEYS"

if ! grep -Fxq "$PUBLIC_KEY" "$AUTHORIZED_KEYS"; then
  echo "$PUBLIC_KEY" >> "$AUTHORIZED_KEYS"
  echo "Installed SSH public key for $USERNAME"
else
  echo "SSH public key already installed for $USERNAME"
fi

# Add to common admin group if present. Debian/Ubuntu typically uses sudo.
if getent group sudo >/dev/null; then
  usermod -aG sudo "$USERNAME"
  echo "Added $USERNAME to sudo group"
elif getent group wheel >/dev/null; then
  usermod -aG wheel "$USERNAME"
  echo "Added $USERNAME to wheel group"
else
  echo "WARNING: no sudo/wheel group found; not adding admin group" >&2
fi

if [[ "$PASSWORDLESS_SUDO" == "true" ]]; then
  if ! command -v sudo >/dev/null 2>&1; then
    echo "ERROR: sudo not installed; cannot configure passwordless sudo" >&2
    exit 1
  fi
  SUDOERS_FILE="/etc/sudoers.d/90-$USERNAME-pi-agent"
  echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" > "$SUDOERS_FILE"
  chmod 440 "$SUDOERS_FILE"
  if command -v visudo >/dev/null 2>&1; then
    visudo -cf "$SUDOERS_FILE" >/dev/null
  fi
  echo "Configured passwordless sudo: $SUDOERS_FILE"
else
  echo "Passwordless sudo not enabled. Re-run with --passwordless-sudo if needed."
fi

# Ensure sshd accepts public key auth if config files are standard.
if [[ -d /etc/ssh/sshd_config.d ]]; then
  SSHD_DROPIN="/etc/ssh/sshd_config.d/90-pi-agent-key-auth.conf"
  cat > "$SSHD_DROPIN" <<'EOF'
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin prohibit-password
EOF
  chmod 644 "$SSHD_DROPIN"
  echo "Wrote SSHD key-auth hardening drop-in: $SSHD_DROPIN"
else
  echo "NOTE: /etc/ssh/sshd_config.d not present; not modifying sshd_config" >&2
fi

if command -v systemctl >/dev/null 2>&1; then
  if systemctl list-unit-files | grep -Eq '^ssh\.service|^sshd\.service'; then
    systemctl reload ssh 2>/dev/null || systemctl reload sshd 2>/dev/null || true
  fi
elif command -v service >/dev/null 2>&1; then
  service ssh reload 2>/dev/null || service sshd reload 2>/dev/null || true
fi

cat <<EOF

Done.

Created/updated user: $USERNAME
Home: $HOME_DIR
Authorized keys: $AUTHORIZED_KEYS
Password locked: yes
Passwordless sudo: $PASSWORDLESS_SUDO

Test from your workstation/container:
  ssh $USERNAME@<nextcloud-vm-ip> 'id && hostname'
EOF
