#!/bin/bash
set -u

CONF="$HOME/.nas-mount.conf"
LOG="$HOME/Library/Logs/nas-mount.log"
LOCK="$HOME/Library/Caches/nas-mount.lock"
NETWAIT=60
HOSTWAIT=45
PORT_TIMEOUT=3

log(){ printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >> "$LOG"; }

if [ -d "$LOCK" ]; then
  if [ -n "$(find "$LOCK" -maxdepth 0 -mmin +10 2>/dev/null)" ]; then
    rmdir "$LOCK" 2>/dev/null
  else
    exit 0
  fi
fi
mkdir -p "$(dirname "$LOCK")" 2>/dev/null
mkdir "$LOCK" 2>/dev/null || exit 0
trap 'rmdir "$LOCK" 2>/dev/null' EXIT

mkdir -p "$(dirname "$LOG")"
[ -f "$CONF" ] || { log "ERROR: $CONF missing"; exit 1; }
. "$CONF"
[ "${#SHARES[@]}" -gt 0 ] || { log "ERROR: SHARES empty"; exit 1; }

urlenc(){
  local s=$1 o="" i c
  for ((i=0; i<${#s}; i++)); do
    c=${s:i:1}
    case "$c" in
      [a-zA-Z0-9.~_-]) o="$o$c" ;;
      *) o="$o$(printf '%%%02X' "'$c")" ;;
    esac
  done
  printf '%s' "$o"
}

as_esc(){ local s=$1; s=${s//\\/\\\\}; s=${s//\"/\\\"}; printf '%s' "$s"; }

mp_alive(){
  local mp="$1" tmp rc n=0 pid
  tmp=$(mktemp /tmp/nasmount.XXXXXX)
  ( /bin/ls -d "$mp/." >/dev/null 2>&1; echo $? > "$tmp" ) 2>/dev/null &
  pid=$!
  while [ $n -lt 6 ]; do
    if [ -s "$tmp" ]; then rc=$(cat "$tmp"); rm -f "$tmp"; return "$rc"; fi
    sleep 1; n=$((n+1))
  done
  kill -9 "$pid" 2>/dev/null; rm -f "$tmp"; return 1
}

n=0
while [ $n -lt $NETWAIT ]; do
  /sbin/route -n get default >/dev/null 2>&1 && break
  sleep 2; n=$((n+2))
done
[ $n -lt $NETWAIT ] || { log "no default route after ${NETWAIT}s"; exit 0; }

for entry in "${SHARES[@]}"; do
  IFS='|' read -r HOST SHARE EUSER EPASS <<< "$entry"
  [ -n "${HOST:-}" ] || continue
  [ -n "${SHARE:-}" ] || continue
  U="${EUSER:-$SMB_USER}"; P="${EPASS:-$SMB_PASS}"
  MP="/Volumes/$SHARE"

  if mount | grep -qF " on $MP ("; then
    mp_alive "$MP" && continue
    log "$SHARE: stale, forcing umount"
    /sbin/umount -f "$MP" >>"$LOG" 2>&1
    sleep 2
  fi

  case "$HOST" in *.*) PROBE="$HOST" ;; *) PROBE="$HOST.local" ;; esac
  hn=0; ok=0
  while [ $hn -lt $HOSTWAIT ]; do
    /usr/bin/nc -z -G "$PORT_TIMEOUT" -w "$PORT_TIMEOUT" "$PROBE" 445 >/dev/null 2>&1 && { ok=1; break; }
    sleep 3; hn=$((hn+3))
  done
  [ $ok -eq 1 ] || { log "$SHARE: $PROBE:445 unreachable after ${HOSTWAIT}s"; continue; }

  SENC=$(urlenc "$SHARE"); UESC=$(as_esc "$U"); PESC=$(as_esc "$P")
  if /usr/bin/osascript >/dev/null 2>>"$LOG" <<EOT
mount volume "smb://${HOST}/${SENC}" as user name "${UESC}" with password "${PESC}"
EOT
  then
    log "$SHARE: mounted from $HOST"
  else
    log "$SHARE: mount FAILED (host=$HOST user=$U)"
  fi
done
