#!/bin/bash
set -euo pipefail

# Configure the one explicitly managed classroom printer. The Ricoh Aficio
# MP C3502 supports PCL 6 as standard; Debian Trixie's compressed Foomatic
# database supplies this generic color PCL 6/PCL XL path without vendor code.

QUEUE="Classroom_Color"
DRIVER="foomatic-db-compressed-ppds:0/ppd/foomatic-ppd/Generic-PCL_6_PCL_XL_Printer-pxlcolor.ppd"
MAKE_MODEL="Ricoh Aficio MP C3502 (Generic PCL 6 Color)"
LOCATION="Ekklesia Classroom"
MAKE_DEFAULT=true

usage() {
    cat <<'USAGE'
Usage: classroom-printer-setup [--no-default] PRINTER-IP-OR-URI

Examples:
  sudo classroom-printer-setup 10.20.30.40
  sudo classroom-printer-setup socket://printer.example.org:9100

An IP address or hostname uses JetDirect/AppSocket on port 9100. Explicit
socket://, ipp://, ipps:// and lpd:// URIs are also accepted.
USAGE
}

log() {
    echo "[classroom-printer-setup] $1"
}

fail() {
    log "ERROR: $1" >&2
    exit 1
}

if [[ "${CLASSROOM_PRINTER_SETUP_TESTING:-false}" != "true" && $EUID -ne 0 ]]; then
    fail "run this command as root: sudo classroom-printer-setup <printer-ip>"
fi

if [[ "${1:-}" == "--no-default" ]]; then
    MAKE_DEFAULT=false
    shift
fi

if [[ $# -ne 1 || "$1" == "-h" || "$1" == "--help" ]]; then
    usage
    [[ $# -eq 1 ]] && exit 0
    exit 2
fi

address="$1"

case "$address" in
    socket://*|ipp://*|ipps://*|lpd://*)
        uri="$address"
        ;;
    *://*)
        fail "unsupported printer URI scheme: $address"
        ;;
    *)
        if [[ ! "$address" =~ ^[A-Za-z0-9._:-]+$ ]]; then
            fail "printer address contains unsupported characters: $address"
        fi
        uri="socket://${address}:9100"
        ;;
esac

for command in lpadmin lpinfo lpstat cupsenable cupsaccept; do
    command -v "$command" >/dev/null 2>&1 || \
        fail "$command is missing; reinstall the ekklesia-classroom package"
done

if ! lpstat -r >/dev/null 2>&1; then
    command -v systemctl >/dev/null 2>&1 && \
        systemctl start cups.service >/dev/null 2>&1 || true
fi

lpstat -r >/dev/null 2>&1 || \
    fail "CUPS is not running; check: systemctl status cups"

models="$(lpinfo -m)" || fail "CUPS could not list installed printer drivers"

if ! grep -q "^${DRIVER} " <<< "$models"; then
    fail "the Debian generic color PCL 6 driver is not installed"
fi

log "configuring ${QUEUE} at ${uri}"

# Repeating this command updates the same named queue; it never creates a
# second destination. None of these operations connects to the printer.
lpadmin \
    -p "$QUEUE" \
    -v "$uri" \
    -m "$DRIVER" \
    -D "$MAKE_MODEL" \
    -L "$LOCATION" || fail "CUPS could not configure ${QUEUE}"

cupsenable "$QUEUE" || fail "CUPS could not enable ${QUEUE}"
cupsaccept "$QUEUE" || fail "CUPS could not accept jobs for ${QUEUE}"

if [[ "$MAKE_DEFAULT" == true ]]; then
    lpadmin -d "$QUEUE" || fail "CUPS could not make ${QUEUE} the default"
fi

log "${QUEUE} is configured, enabled and accepting jobs."

if [[ "$MAKE_DEFAULT" == true ]]; then
    log "${QUEUE} is the system default printer."
fi

log "The printer may remain offline until it is reachable; this does not affect boot."
