#!/bin/bash

# FORFIRM Corporate Printers
# Deploys and repairs corporate printers using native CUPS queues.
# Intended for Microsoft Intune macOS shell scripts running as root.

set -u
set -o pipefail

SCRIPT_VERSION="1.0.0"

BASE_DIR="/Users/Shared/FORFIRM"
LOG_DIR="${BASE_DIR}/Logs"
LOG_FILE="${LOG_DIR}/printers-install.log"

# Set to true only after removing/excluding the legacy printer profile.
REMOVE_LEGACY_MCX_QUEUES=true

# Printer definitions:
# queue_name|display_name|location|device_uri|ppd_path
PRINTERS=(
  "FORFIRM_Sala_Riunioni|Lugano - Sala Riunioni|Lugano - Sala Riunioni|ipp://pr-sala-riunioni.forfirm.internal|/Library/Printers/PPDs/Contents/Resources/Xerox AltaLink C8130.gz"
  "FORFIRM_Ufficio_Partner|Lugano - Ufficio Partner|Lugano - Ufficio Partner|ipp://pr-ufficio-partner.forfirm.internal|/Library/Printers/PPDs/Contents/Resources/Xerox VersaLink C415 Color MFP.gz"
)

LEGACY_QUEUES=(
  "mcx_0"
  "mcx_1"
)

mkdir -p "$LOG_DIR"
chmod 755 "$BASE_DIR" "$LOG_DIR" 2>/dev/null || true

log() {
  local message="$1"
  printf '%s - %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$message" | tee -a "$LOG_FILE"
}

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

queue_exists() {
  /usr/bin/lpstat -p "$1" >/dev/null 2>&1
}

get_queue_uri() {
  /usr/bin/lpstat -v "$1" 2>/dev/null |
    /usr/bin/awk -F': ' 'NR == 1 {print $2}'
}

remove_queue() {
  local queue_name="$1"

  if queue_exists "$queue_name"; then
    log "Removing printer queue: ${queue_name}"
    if ! /usr/sbin/lpadmin -x "$queue_name" >>"$LOG_FILE" 2>&1; then
      log "WARNING: Could not remove queue ${queue_name}."
      return 1
    fi
  fi

  return 0
}

install_queue() {
  local queue_name="$1"
  local display_name="$2"
  local location="$3"
  local device_uri="$4"
  local ppd_path="$5"

  if [[ ! -f "$ppd_path" ]]; then
    log "ERROR: Required PPD not found: ${ppd_path}"
    return 1
  fi

  log "Creating printer '${display_name}' as queue '${queue_name}'."

  if ! /usr/sbin/lpadmin \
      -p "$queue_name" \
      -E \
      -v "$device_uri" \
      -P "$ppd_path" \
      -D "$display_name" \
      -L "$location" \
      -o printer-is-shared=false \
      >>"$LOG_FILE" 2>&1; then
    log "ERROR: lpadmin failed while creating ${queue_name}."
    return 1
  fi

  # Corporate defaults. Remove or modify these if different defaults are required.
  /usr/bin/lpoptions -p "$queue_name" -o PageSize=A4 >>"$LOG_FILE" 2>&1 || \
    log "WARNING: Could not set A4 as the default for ${queue_name}."

  /usr/bin/lpoptions -p "$queue_name" -o Duplex=DuplexNoTumble >>"$LOG_FILE" 2>&1 || \
    log "WARNING: Could not set duplex printing for ${queue_name}."

  /usr/sbin/cupsenable "$queue_name" >>"$LOG_FILE" 2>&1 || \
    log "WARNING: Could not enable ${queue_name}."

  /usr/sbin/cupsaccept "$queue_name" >>"$LOG_FILE" 2>&1 || \
    log "WARNING: Could not configure ${queue_name} to accept jobs."

  return 0
}

verify_queue() {
  local queue_name="$1"
  local expected_uri="$2"

  if ! queue_exists "$queue_name"; then
    log "ERROR: Queue ${queue_name} was not found after installation."
    return 1
  fi

  local actual_uri
  actual_uri="$(get_queue_uri "$queue_name")"

  if [[ "$actual_uri" != "$expected_uri" ]]; then
    log "ERROR: Queue ${queue_name} has URI '${actual_uri}', expected '${expected_uri}'."
    return 1
  fi

  if ! /usr/bin/lpoptions -p "$queue_name" -l >/dev/null 2>&1; then
    log "ERROR: Queue ${queue_name} does not expose valid printer options."
    return 1
  fi

  log "Verified printer queue ${queue_name}."
  return 0
}

repair_or_install_queue() {
  local queue_name="$1"
  local display_name="$2"
  local location="$3"
  local device_uri="$4"
  local ppd_path="$5"

  if queue_exists "$queue_name"; then
    local current_uri
    current_uri="$(get_queue_uri "$queue_name")"

    if [[ "$current_uri" == "$device_uri" ]] &&
       /usr/bin/lpoptions -p "$queue_name" -l >/dev/null 2>&1; then
      log "Printer '${display_name}' is already installed and valid."

      /usr/sbin/cupsenable "$queue_name" >>"$LOG_FILE" 2>&1 || true
      /usr/sbin/cupsaccept "$queue_name" >>"$LOG_FILE" 2>&1 || true
      return 0
    fi

    log "Existing queue ${queue_name} is invalid or has changed. Recreating it."
    remove_queue "$queue_name" || return 1
  fi

  install_queue \
    "$queue_name" \
    "$display_name" \
    "$location" \
    "$device_uri" \
    "$ppd_path" || return 1

  verify_queue "$queue_name" "$device_uri"
}

main() {
  if [[ "$EUID" -ne 0 ]]; then
    fail "This script must run as root. Configure the Intune script to run as the signed-in user: No."
  fi

  log "============================================================"
  log "Starting FORFIRM Corporate Printers deployment v${SCRIPT_VERSION}."
  log "macOS version: $(/usr/bin/sw_vers -productVersion 2>/dev/null || echo unknown)"

  if [[ "$REMOVE_LEGACY_MCX_QUEUES" == true ]]; then
    for legacy_queue in "${LEGACY_QUEUES[@]}"; do
      remove_queue "$legacy_queue" || true
    done
  fi

  local failures=0

  for definition in "${PRINTERS[@]}"; do
    IFS='|' read -r queue_name display_name location device_uri ppd_path <<< "$definition"

    if ! repair_or_install_queue \
        "$queue_name" \
        "$display_name" \
        "$location" \
        "$device_uri" \
        "$ppd_path"; then
      failures=$((failures + 1))
    fi
  done

  # Restart the print service so applications refresh their printer list.
  log "Refreshing the CUPS print service."
  /bin/launchctl kickstart -k system/org.cups.cupsd >>"$LOG_FILE" 2>&1 || \
    log "WARNING: Could not restart cupsd; queues were still created."

  /bin/sleep 2

  log "Current printer status:"
  /usr/bin/lpstat -t 2>&1 | tee -a "$LOG_FILE"

  if [[ "$failures" -gt 0 ]]; then
    fail "${failures} printer queue(s) failed installation or verification."
  fi

  log "FORFIRM Corporate Printers deployment completed successfully."
  exit 0
}

main "$@"
