#!/bin/bash
#
#  Add the "Neubarth" printer (HP Envy 6500e) to this Mac.
#
#  Run with:
#      curl -fsSL https://printers.4tmrw.net/2961/neubarth.sh | bash
#
#  No driver download needed - this printer speaks AirPrint / IPP Everywhere,
#  so macOS builds the driver itself by asking the printer what it supports.
#
#  If the printer's address ever changes you can override it without
#  re-hosting this file:
#      curl -fsSL https://printers.4tmrw.net/2961/neubarth.sh | PRINTER_IP=10.45.7.99 bash
#
#  Make it the default printer too:
#      curl -fsSL https://printers.4tmrw.net/2961/neubarth.sh | SET_AS_DEFAULT=yes bash
#
#  GENERATED FILE - do not edit directly. Edit template.sh / printers.tsv
#  and re-run ./build.sh.
#
SCRIPT_VERSION="2.0"

set -u

# ---- settings (overridable by environment variable) ------------------------
PRINTER_IP="${PRINTER_IP:-10.45.7.73}"
QUEUE_NAME="${QUEUE_NAME:-Neubarth}"
LOCATION="${LOCATION:-TGL}"
EXPECT_MODEL="${EXPECT_MODEL:-Envy 6500e}"
SET_AS_DEFAULT="${SET_AS_DEFAULT:-no}"
# ---------------------------------------------------------------------------

if [ -t 1 ]; then C_G=$'\033[32m'; C_R=$'\033[31m'; C_0=$'\033[0m'
else C_G=""; C_R=""; C_0=""; fi
ok()   { printf '  %sOK%s   %s\n'   "$C_G" "$C_0" "$*"; }
bad()  { printf '  %sFAIL%s %s\n'   "$C_R" "$C_0" "$*"; }
info() { printf '       %s\n' "$*"; }
say()  { printf '%s\n' "$*"; }

# Scratch dir for IPP test files.
#
# IMPORTANT: these must be real files, NOT heredocs piped to `ipptool
# /dev/stdin`. When this script is run as `curl ... | bash`, stdin is the
# script itself, so /dev/stdin is not safe to hand to another program.
TMPD="$(mktemp -d "${TMPDIR:-/tmp}/addprinter.XXXXXX")" || {
    bad "Couldn't create a temporary folder."; exit 1; }
cleanup() { rm -rf "$TMPD"; }
trap cleanup EXIT INT TERM

say ""
say "Adding printer \"$QUEUE_NAME\"  ($PRINTER_IP)   [installer v$SCRIPT_VERSION]"
say "======================================================================"

# --- 1. permission to add printers -----------------------------------------
# Admin users belong to _lpadmin and need no password; others get a sudo
# prompt. sudo reads the password from the terminal, not stdin, so this still
# works when the script arrives through a pipe.
if id -Gn 2>/dev/null | tr ' ' '\n' | grep -qx "_lpadmin"; then
    LP=(lpadmin); ok "You can add printers without a password."
else
    LP=(sudo lpadmin)
    info "You'll be asked for your Mac login password."
    if ! sudo -v 2>/dev/null; then
        bad "Couldn't get permission to add a printer."
        info "Ask whoever administers this Mac to run this for you."
        exit 1
    fi
fi

# --- 2. is the printer reachable? ------------------------------------------
# Bonjour/AirPrint auto-discovery does NOT work on this network - the Wi-Fi
# drops the multicast traffic discovery depends on - so these printers never
# show up by themselves in the printer list. That's why we add them by IP.
if ! /usr/bin/nc -z -G 5 "$PRINTER_IP" 631 >/dev/null 2>&1; then
    bad "Can't reach the printer at $PRINTER_IP."
    say ""
    info "Check that:"
    info "  - you're on the office Wi-Fi (not a guest network)"
    info "  - any VPN is disconnected - a VPN will hide the printer"
    info "  - the printer is powered on (its screen should be lit)"
    say ""
    exit 1
fi
ok "Printer is reachable."

# --- 3. is it actually the right printer? ----------------------------------
# These use DHCP addresses, so an IP could one day belong to a different
# device. Ask it what it is before trusting it.
cat > "$TMPD/id.test" <<'IPPTEST'
{
  OPERATION Get-Printer-Attributes
  GROUP operation-attributes-tag
  ATTR charset attributes-charset utf-8
  ATTR language attributes-natural-language en
  ATTR uri printer-uri $uri
  DISPLAY printer-device-id
}
IPPTEST

MODEL="$(ipptool -t "ipp://$PRINTER_IP/ipp/print" "$TMPD/id.test" 2>/dev/null \
         | sed -n 's/.*MDL:\([^;]*\);.*/\1/p' | head -1)"

if [ -z "$MODEL" ]; then
    info "Couldn't read the model name; continuing anyway."
elif printf '%s' "$MODEL" | grep -q "$EXPECT_MODEL"; then
    ok "Confirmed: $MODEL"
else
    bad "$PRINTER_IP is a '$MODEL', not a $EXPECT_MODEL."
    say ""
    info "That printer's address has probably changed. Ask IT for the new one,"
    info "then run this instead (substituting the new address):"
    info "  curl -fsSL https://printers.4tmrw.net/2961/neubarth.sh | PRINTER_IP=x.x.x.x bash"
    say ""
    exit 1
fi

# --- 4. add (or refresh) the queue -----------------------------------------
# Safe to re-run: an existing queue of the same name is removed first, so you
# always end up with one clean correct queue rather than "Neubarth-2".
#
# NOTE: don't test existence with `lpstat -p NAME` - it exits 0 even when the
# queue does NOT exist, if NAME matches a driverless printer's own advertised
# service name. `lpstat -v` lists only real queues.
if lpstat -v 2>/dev/null | grep -q "^device for ${QUEUE_NAME}:"; then
    info "A printer called \"$QUEUE_NAME\" already exists - replacing it."
    "${LP[@]}" -x "$QUEUE_NAME" >/dev/null 2>&1
fi

if "${LP[@]}" -p "$QUEUE_NAME" \
       -v "ipps://$PRINTER_IP/ipp/print" \
       -m everywhere \
       -D "HP Envy 6500e ($QUEUE_NAME)" \
       -L "$LOCATION" \
       -o printer-is-shared=false \
       -E 2>"$TMPD/err"; then
    ok "Printer added."
else
    bad "Could not add the printer."
    sed 's/^/       /' "$TMPD/err" 2>/dev/null
    exit 1
fi

cupsenable "$QUEUE_NAME" >/dev/null 2>&1
cupsaccept "$QUEUE_NAME" >/dev/null 2>&1

if [ "$SET_AS_DEFAULT" = "yes" ]; then
    lpoptions -d "$QUEUE_NAME" >/dev/null 2>&1 && ok "Set as the default printer."
fi

# --- 5. prove it works ------------------------------------------------------
# Validate-Job asks "would you accept a job from me?" - a genuine end-to-end
# check that uses no paper or ink.
#
# NOTE: needs -tv, not -t. Plain -t prints only "[PASS]" and omits the
# status-code line this greps for.
cat > "$TMPD/val.test" <<'IPPTEST'
{
  OPERATION Validate-Job
  GROUP operation-attributes-tag
  ATTR charset attributes-charset utf-8
  ATTR language attributes-natural-language en
  ATTR uri printer-uri $uri
  ATTR mimeMediaType document-format image/pwg-raster
}
IPPTEST

RESULT="$(ipptool -tv "ipp://localhost/printers/$QUEUE_NAME" "$TMPD/val.test" \
          2>/dev/null | grep -c "successful-ok")"

say ""
if [ "${RESULT:-0}" -ge 1 ]; then
    ok "Verified - the printer accepted a test job request."
    say ""
    say "Done. \"$QUEUE_NAME\" is ready to use in any app's Print dialog."
    say ""
else
    bad "The printer was added but did not accept a test job."
    info "Try printing anyway; if it fails, run this script again."
    say ""
    exit 1
fi
