#!/bin/sh
# hamthings-node-apply — APPLICATORE della config HamThings sul Pi-Star, guidato dal conf
# (unica fonte di verita'). Girato dal websave (salvataggio) E al BOOT (vedi NB sotto).
# ENFORCE delle SOLE tecnologie ATTIVE: cosi' al boot NON litighiamo con Pi-Star sulle
# tecnologie che il sysop ha disattivato (quelle le spegne il websave al momento). Copre:
# base (callsign/id/freq/duplex), D-Star, YSF, DMR + le patch di visualizzazione. Il modem NON
# si tocca (hardware -> resta di Pi-Star).
# NB: e' lanciato al boot da hamthings-node-apply.service (After=network-online.target). NON e'
# ordinato dopo pistar-bootconfig: quest'ultimo gira da /etc/rc.local SOLO se sul boot c'e' uno
# zip di config, quindi in un avvio normale non interferisce.
CONF=/opt/hamthings-node/hamthings-node.conf
[ -r "$CONF" ] || exit 0
MM=/etc/mmdvmhost; YSFG=/etc/ysfgateway; DR=/etc/dstarrepeater
FN=/var/www/dashboard/mmdvmhost/functions.php
HOSTS=/root/YSFHosts.txt   # id;name;desc;addr;port -> id->ip dei master pubblici

val(){ sed -n "s/^[[:space:]]*$1[[:space:]]*=[[:space:]]*\([^#]*\).*/\1/p" "$CONF" | head -1 | sed 's/[[:space:]]*$//'; }
ip_of(){ awk -F';' -v id="$1" '$1==id{print $4; exit}' "$HOSTS" 2>/dev/null; }
CALL=$(val callsign); DMRID=$(val dmrid); RXF=$(val rxfreq); TXF=$(val txfreq); DUP=$(val duplex)
DSTAR=$(val dstar); MOD=$(val module); MASTER=$(val master); PORT=$(val port)
YS=$(val ysf); YM=$(val ysf_master); YT=$(val ysf_token)
DMR=$(val dmr); DM=$(val dmr_master); DMPW=$(val dmr_password)
CC=$(val colorcode); ELC=$(val embedded_lc); DTA=$(val dump_ta)
[ -n "$PORT" ] || PORT=20010; [ -n "$MOD" ] || MOD=B

case "$CALL" in ''|IU0XYZ|CHANGEME) exit 0 ;; esac

# set_ini: chiave=valore DENTRO [sezione]; INSERISCE se manca; PRESERVA permessi (cat, non mv).
set_ini(){ awk -v s="[$2]" -v k="$3" -v v="$4" '
    $0==s{inS=1;print;next}
    /^\[/&&$0!=s{ if(inS&&!d){print k"="v; d=1} inS=0 }
    inS&&$0~"^"k"="{print k"="v; d=1; next}
    {print}
    END{ if(inS&&!d) print k"="v }
  ' "$1" > "$1.hnw" && cat "$1.hnw" > "$1" && rm -f "$1.hnw"; }
fw_open(){ command -v iptables >/dev/null 2>&1 || return 0; [ -n "$1" ] || return 0
  iptables -C OUTPUT -p udp -d "$1" --dport "$2" -j ACCEPT 2>/dev/null || iptables -I OUTPUT -p udp -d "$1" --dport "$2" -j ACCEPT 2>/dev/null; }

RW=0; if ! touch "$MM" 2>/dev/null; then mount -o remount,rw / 2>/dev/null && RW=1; fi
[ -f "$DR" ] && [ ! -f "$DR.ht-orig" ] && cp -a "$DR" "$DR.ht-orig" 2>/dev/null   # backup una-tantum (revert RPT1)

# --- BASE (solo valori presenti: non azzeriamo mai la config Pi-Star) -----------------------------
if [ -f "$MM" ]; then
  [ -n "$CALL" ]  && set_ini "$MM" "General" "Callsign" "$CALL"
  [ -n "$DMRID" ] && set_ini "$MM" "General" "Id" "$DMRID"
  [ -n "$DUP" ]   && set_ini "$MM" "General" "Duplex" "$DUP"
  [ -n "$RXF" ]   && set_ini "$MM" "Info" "RXFrequency" "$RXF"
  [ -n "$TXF" ]   && set_ini "$MM" "Info" "TXFrequency" "$TXF"
fi

# --- D-Star (solo se attivo) ----------------------------------------------------------------------
if [ "$DSTAR" = 1 ] && [ -f "$MM" ]; then
  MIP=$(getent hosts "$MASTER" 2>/dev/null | awk '{print $1; exit}'); [ -n "$MIP" ] || MIP="$MASTER"
  fw_open "$MIP" "$PORT"
  set_ini "$MM" "D-Star" "Enable" "1"
  set_ini "$MM" "D-Star" "Module" "$MOD"
  set_ini "$MM" "D-Star" "RemoteGateway" "1"
  set_ini "$MM" "D-Star Network" "Enable" "1"
  set_ini "$MM" "D-Star Network" "GatewayAddress" "$MIP"
  set_ini "$MM" "D-Star Network" "GatewayPort" "20001"
  set_ini "$MM" "D-Star Network" "LocalPort" "20011"
  [ -f "$DR" ] && grep -q '^callsign=' "$DR" 2>/dev/null && { sed -i "s/^\(callsign=.*\)./\1$MOD/" "$DR" 2>/dev/null; chmod 644 "$DR" 2>/dev/null; }
  [ -f "$FN" ] && ! grep -q 'hamthings-node' "$FN" 2>/dev/null && \
    sed -i 's/isProcessRunning("ircddbgatewayd")/(isProcessRunning("ircddbgatewayd") || isProcessRunning("hamthings-node"))/' "$FN" 2>/dev/null
  echo "[hn-apply] D-Star ON mod $MOD -> RemoteGateway $MIP:20001"
fi

# --- YSF (solo se attivo) -------------------------------------------------------------------------
if [ "$YS" = 1 ] && [ -f "$MM" ]; then
  set_ini "$MM" "System Fusion" "Enable" "1"
  set_ini "$MM" "System Fusion Network" "Enable" "1"
  if [ -f "$YSFG" ] && [ -n "$YM" ]; then
    set_ini "$YSFG" "Network" "Startup" "HamThings-$YM"
    [ -n "$YT" ] && set_ini "$YSFG" "Network" "Options" "$YT"
    # Porta YSF (42000) in uscita verso il master: senza, su un nodo con policy OUTPUT DROP il
    # poll del gateway muore sul firewall del nodo stesso. Il gateway logga comunque "Linked"
    # (YSF e' connectionless, non attende risposta), ma al master non arriva NULLA e il C4FM non
    # funziona. D-Star e DMR avevano gia' il loro fw_open; l'YSF era l'unico senza.
    MYIP=$(ip_of "$YM"); [ -n "$MYIP" ] || MYIP=$(getent hosts "$YM" 2>/dev/null | awk '{print $1; exit}')
    fw_open "$MYIP" 42000
    systemctl enable ysfgateway >/dev/null 2>&1 || true
    systemctl restart ysfgateway >/dev/null 2>&1 || true
  fi
  echo "[hn-apply] YSF ON -> reflector HamThings-$YM (fw 42000 -> ${MYIP:-?})"
fi

# --- DMR (solo se attivo) — MMDVMHost DIRETTO al master (come RemoteGateway, niente DMRGateway) ---
if [ "$DMR" = 1 ] && [ -f "$MM" ]; then
  DMIP=$(ip_of "$DM")
  fw_open "$DMIP" 62031
  set_ini "$MM" "DMR" "Enable" "1"
  [ -n "$CC" ]  && set_ini "$MM" "DMR" "ColorCode" "$CC"
  [ -n "$ELC" ] && set_ini "$MM" "DMR" "EmbeddedLCOnly" "$ELC"
  [ -n "$DTA" ] && set_ini "$MM" "DMR" "DumpTAData" "$DTA"
  if [ -n "$DMIP" ]; then
    set_ini "$MM" "DMR Network" "Enable" "1"
    set_ini "$MM" "DMR Network" "Type" "Direct"
    set_ini "$MM" "DMR Network" "Address" "$DMIP"
    set_ini "$MM" "DMR Network" "Port" "62031"
    set_ini "$MM" "DMR Network" "RemoteAddress" "$DMIP"
    set_ini "$MM" "DMR Network" "RemotePort" "62031"
    [ -n "$DMPW" ] && set_ini "$MM" "DMR Network" "Password" "$DMPW"
  fi
  echo "[hn-apply] DMR ON -> diretto $DMIP:62031"
fi

[ "$RW" = 1 ] && mount -o remount,ro / 2>/dev/null
systemctl restart mmdvmhost 2>/dev/null || true
exit 0
