#!/usr/bin/bash
#
# powerman/setup.sh — idempotent powerman setup for Cyclades PM10i PDU
#
# Creates a stable udev symlink for the USB-DB9 adapter, writes powerman.conf
# with 10 outlet nodes, and enables + starts powermand.
#
# This script is designed to be run ON the target host (pfv-tsys1) as root.
# It is idempotent: safe to run multiple times.
#
# Usage:
#   PROX_HOST=pfv-tsys1 bash tests/remote.sh prox-file powerman/setup.sh
#
# Override defaults via environment variables:
#   PDU_SERIAL   — USB adapter serial (default: BJAAb144J07)
#   PDU_VENDOR   — USB vendor ID       (default: 067b)
#   PDU_DEV_NAME — udev symlink name   (default: cyclades-pm10)
#   PDU_BAUD     — serial baud rate    (default: 9600,8n1)
#   PDU_TYPE     — powerman spec type  (default: pm10)
#   PDU_OUTLETS  — number of outlets   (default: 10)
#   PDU_LISTEN   — powermand listen    (default: 0.0.0.0:10101)
#
set -euo pipefail

# --- Config (overridable via env) ---
PDU_SERIAL="${PDU_SERIAL:-BJAAb144J07}"
PDU_VENDOR="${PDU_VENDOR:-067b}"
PDU_DEV_NAME="${PDU_DEV_NAME:-cyclades-pm10}"
PDU_BAUD="${PDU_BAUD:-9600,8n1}"
PDU_TYPE="${PDU_TYPE:-pm10}"
PDU_OUTLETS="${PDU_OUTLETS:-10}"
PDU_LISTEN="${PDU_LISTEN:-}"  # Auto-detect Tailscale IP if empty

UDEV_RULE="/etc/udev/rules.d/99-cyclades-pdu.rules"
POWERMAN_CONF="/etc/powerman/powerman.conf"
DEV_FILE="/etc/powerman/cyclades-pm10.dev"

# --- Auto-detect Tailscale IP for listen address ---
if [ -z "$PDU_LISTEN" ]; then
  TS_IP=$(tailscale ip -4 2>/dev/null || true)
  if [ -n "$TS_IP" ]; then
    PDU_LISTEN="${TS_IP}:10101"
    echo "  Auto-detected Tailscale IP: $TS_IP"
  else
    PDU_LISTEN="127.0.0.1:10101"
    echo "  WARNING: No Tailscale IP detected. Defaulting to localhost."
  fi
fi

echo "============================================"
echo "  Powerman PDU Setup"
echo "  Host: $(hostname)"
echo "  PDU:  Cyclades PM${PDU_OUTLETS}i"
echo "  Adapter serial: $PDU_SERIAL"
echo "  Device symlink: /dev/$PDU_DEV_NAME"
echo "  Listen: $PDU_LISTEN (Tailscale only)"
echo "============================================"

# --- 1. Ensure powerman is installed ---
echo ""
echo "--- [1/5] Checking powerman installation ---"
if ! dpkg -l powerman 2>/dev/null | grep -q '^ii'; then
  echo "  Installing powerman from Debian repo..."
  apt-get update -qq && apt-get install -y -qq powerman
else
  echo "  Powerman already installed: $(dpkg -l powerman | awk '/^ii/{print $3}')"
fi

# --- 2. Create udev rule for stable device name ---
echo ""
echo "--- [2/5] Creating udev rule for USB-DB9 adapter ---"
cat > "$UDEV_RULE" <<UDEV
# Stable symlink for Cyclades PM10i PDU USB-DB9 adapter
# Generated by powerman/setup.sh
SUBSYSTEM=="tty", ATTRS{idVendor}=="${PDU_VENDOR}", ATTRS{serial}=="${PDU_SERIAL}", GROUP="dialout", MODE="0660", SYMLINK+="${PDU_DEV_NAME}"
UDEV
echo "  Written: $UDEV_RULE"

# Trigger udev to create the symlink now
udevadm control --reload-rules 2>/dev/null || true
udevadm trigger --subsystem-match=tty 2>/dev/null || true
sleep 1

if [ -e "/dev/${PDU_DEV_NAME}" ]; then
  echo "  Device symlink active: /dev/${PDU_DEV_NAME} -> $(readlink -f "/dev/${PDU_DEV_NAME}")"
else
  echo "  WARNING: /dev/${PDU_DEV_NAME} not found yet. Adapter may be unplugged."
  echo "  Falling back to /dev/ttyUSB* discovery..."
  # Try to find any ttyUSB device as fallback
  for tty in /dev/ttyUSB*; do
    if [ -e "$tty" ]; then
      echo "  Found: $tty (using as fallback)"
      PDU_DEV_NAME="$(basename "$tty")"
      break
    fi
  done
fi

# --- 2b. Ensure powermand user can access the serial device ---
echo ""
echo "--- [2b/5] Fixing serial device permissions ---"
if id powerman >/dev/null 2>&1; then
  if id powerman | grep -qv dialout; then
    usermod -aG dialout powerman
    echo "  Added 'powerman' user to 'dialout' group"
  else
    echo "  'powerman' already in 'dialout' group"
  fi
else
  echo "  (no powerman user — service may run as root)"
fi

# --- 3. Write powerman.conf ---
echo ""
echo "--- [3/5] Writing powerman.conf ---"

# Build node definitions
NODES=""
for i in $(seq 1 "$PDU_OUTLETS"); do
  NODES+="node \"outlet-${i}\" \"${PDU_DEV_NAME}\" \"${i}\"\n"
done

cat > "$POWERMAN_CONF" <<PMCONF
# Powerman configuration for Cyclades PM${PDU_OUTLETS}i PDU
# Generated by powerman/setup.sh on $(date)
# Device: /dev/${PDU_DEV_NAME} (USB-DB9 adapter serial ${PDU_SERIAL})

# Listen on localhost (for local admin) and Tailscale (for remote access)
listen "127.0.0.1:10101"
listen "${PDU_LISTEN}"

# Device specification for Cyclades PM10
include "${DEV_FILE}"

# The PDU device (serial-attached)
device "${PDU_DEV_NAME}" "${PDU_TYPE}" "/dev/${PDU_DEV_NAME}" "${PDU_BAUD}"

# Outlet nodes (rename these to match attached devices when onsite)
$(printf '%b' "$NODES")
PMCONF

echo "  Written: $POWERMAN_CONF"
echo "  Nodes defined: outlet-1 through outlet-${PDU_OUTLETS}"

# --- 4. Restart powermand ---
echo ""
echo "--- [4/5] Restarting powermand ---"
systemctl enable powerman 2>/dev/null || true
systemctl restart powerman 2>/dev/null || true
sleep 2

if systemctl is-active --quiet powerman; then
  echo "  powermand is running."
else
  echo "  WARNING: powermand failed to start. Check journalctl -u powerman"
  journalctl -u powerman --no-pager -n 20 2>/dev/null || true
fi

# --- 5. Verify ---
echo ""
echo "--- [5/5] Verification ---"
echo ""
echo "  powerman -l (list all outlets):"
powerman -l 2>&1 || echo "(powerman -l failed)"

echo ""
echo "  powerman -q (query status):"
powerman -q 2>&1 || echo "(powerman -q failed — PDU may need a moment)"

echo ""
echo "============================================"
echo "  Setup complete."
echo ""
echo "  Outlet names are generic (outlet-1 ... outlet-${PDU_OUTLETS})."
echo "  Rename them in ${POWERMAN_CONF} when onsite to match attached devices."
echo ""
echo "  Test:    powerman -0 outlet-10   (off)"
echo "           powerman -1 outlet-10   (on)"
echo "           powerman -c outlet-10   (cycle)"
echo "           powerman -q             (status)"
echo "============================================"
