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

# Hardcoded NetBox access (DEV ONLY!)
NETBOX_URL="http://netbox.gt-tiso.ikeja.co.za"
NETBOX_TOKEN="7648e4f5ee370cda7834682e61b47c2ee8e95623"

usage() {
  cat >&2 <<EOF
Usage: nbplay [--pwfile PATH] [--user USER] <playbook.yml> <device_name> [ansible-playbook args...]
  --pwfile PATH   Path to password/vars file:
                    - YAML/JSON: must contain ansible_ssh_pass (and optionally ansible_user)
                    - Plain text: first line is the password (wrapped as ansible_ssh_pass)
  --user USER     ansible_user to use (overrides file value unless omitted)
Examples:
  nbplay uptime.yml ikeja12345 --pwfile /opt/containers/ansible-worker/data/ssh.yml
  nbplay uptime.yml ikeja12345 --pwfile /opt/.../ssh.txt --user root
EOF
  exit 2
}

# ---- Parse args
PWFILE=""
USER_OVERRIDE=""
ARGS=()
while (( $# )); do
  case "${1:-}" in
    --pwfile) shift; PWFILE="${1:-}"; [[ -n "$PWFILE" ]] || usage; shift;;
    --user)   shift; USER_OVERRIDE="${1:-}"; [[ -n "$USER_OVERRIDE" ]] || usage; shift;;
    -h|--help) usage;;
    *) ARGS+=("$1"); shift;;
  esac
done
set -- "${ARGS[@]}"

if [[ $# -lt 2 ]]; then usage; fi
PLAYBOOK="$1"; shift
NAME="$1"; shift

if [[ -z "${PWFILE}" ]]; then
  DEFAULT_PWFILE="${NBPLAY_PWFILE:-/opt/containers/ansible-worker/data/ssh.yml}"
  if [[ -f "$DEFAULT_PWFILE" ]]; then
    PWFILE="$DEFAULT_PWFILE"
  fi
fi

# ---- Deps
command -v jq >/dev/null 2>&1 || { echo "jq not found" >&2; exit 127; }
command -v curl >/dev/null 2>&1 || { echo "curl not found" >&2; exit 127; }

BASE="${NETBOX_URL%/}"
hdr=(-H "Authorization: Token ${NETBOX_TOKEN}" -H "Accept: application/json")

# ---- Resolve device -> IP
dev_json="$(curl -fsS "${hdr[@]}" "${BASE}/api/dcim/devices/?name=${NAME}&limit=1")"
count="$(printf '%s' "$dev_json" | jq -r '.count // 0')"
if [[ "$count" != "1" ]]; then
  echo "Device '${NAME}' not found or not unique (count=${count})." >&2
  exit 1
fi
addr_v4="$(printf '%s' "$dev_json" | jq -r '.results[0].primary_ip4.address // empty')"
addr_v6="$(printf '%s' "$dev_json" | jq -r '.results[0].primary_ip6.address // empty')"
addr_any="$(printf '%s' "$dev_json" | jq -r '.results[0].primary_ip.address // empty')"
addr="${addr_v4:-${addr_v6:-${addr_any:-}}}"
[[ -n "$addr" && "$addr" != "null" ]] || { echo "Device '${NAME}' has no primary IP." >&2; exit 1; }
ip="${addr%%/*}"

# ---- Temp inventory
tmpinv="$(mktemp)"; trap 'rm -f "$tmpinv" "$tmpvars"' EXIT
cat >"$tmpinv" <<EOF
[nb]
$NAME ansible_host=$ip
EOF

# ---- Build extra-vars without leaking secrets in ps
extravars=()
tmpvars=""

if [[ -n "$PWFILE" ]]; then
  if [[ "$PWFILE" =~ \.(ya?ml|json)$ ]]; then
    # Must contain: ansible_ssh_pass (and optionally ansible_user)
    extravars+=(-e "@${PWFILE}")
  else
    # Wrap plain text password into a tiny YAML
    [[ -r "$PWFILE" ]] || { echo "Password file not readable: $PWFILE" >&2; exit 1; }
    pass="$(head -n1 "$PWFILE" | tr -d '\r\n')"
    tmpvars="$(mktemp)"
    {
      echo "ansible_ssh_pass: \"$pass\""
      [[ -n "$USER_OVERRIDE" ]] && echo "ansible_user: \"$USER_OVERRIDE\""
    } > "$tmpvars"
    chmod 600 "$tmpvars"
    extravars+=(-e "@${tmpvars}")
  fi
fi

# If user override provided and not already set via tmpvars/YAML, add it safely
if [[ -n "$USER_OVERRIDE" && -z "$tmpvars" ]]; then
  tmpvars="$(mktemp)"
  echo "ansible_user: \"$USER_OVERRIDE\"" > "$tmpvars"
  chmod 600 "$tmpvars"
  extravars+=(-e "@${tmpvars}")
fi

# ---- Run playbook (do NOT use --ask-pass)
ANSIBLE_ASK_PASS=False exec ansible-playbook -i "$tmpinv" "$PLAYBOOK" -l "$NAME" \
  "${extravars[@]}" "$@"
