#!/bin/bash
# Deploy QMI files from /app/qmiPkg and switch from PPP to QMI.
# Because stopping PPP disconnects the network (and SSH), the switch step runs under nohup.
# Usage: /app/ppp-to-qmi-switch
#        or: nohup /app/ppp-to-qmi-switch &
# Logs: /app/qmi-log/ppp-to-qmi-switch.log

QMI_LOG_DIR="/app/qmi-log"
mkdir -p "$QMI_LOG_DIR" 2>/dev/null || true
LOG="${LOG:-$QMI_LOG_DIR/ppp-to-qmi-switch.log}"
SRC_DIR="/app/qmiPkg"

log() {
	echo "$(date -Iseconds) $*" | tee -a "$LOG"
}

wait_for_cdc_wdm0() {
	local wait_sec="${1:-90}"
	while [ "$wait_sec" -gt 0 ]; do
		if [ -c /dev/cdc-wdm0 ]; then
			return 0
		fi
		log "waiting for /dev/cdc-wdm0 ... (${wait_sec}s)"
		sleep 2
		wait_sec=$((wait_sec - 2))
	done
	return 1
}

find_qmi_iface() {
	local n p
	for p in /sys/class/net/*; do
		[ -d "$p" ] || continue
		n="${p##*/}"
		[ -f "/sys/class/net/$n/qmi/raw_ip" ] && echo "$n" && return 0
	done
	return 1
}

wait_for_qmi_iface() {
	local wait_sec="${1:-90}"
	while [ "$wait_sec" -gt 0 ]; do
		if find_qmi_iface >/dev/null 2>&1; then
			return 0
		fi
		log "waiting for QMI net iface (qmi/raw_ip) ... (${wait_sec}s)"
		sleep 2
		wait_sec=$((wait_sec - 2))
	done
	return 1
}

dump_net_snapshot() {
	log "debug: /sys/class/net = $(ls -1 /sys/class/net 2>/dev/null | tr '\n' ' ')"
	if command -v ip >/dev/null 2>&1; then
		ip link 2>/dev/null | sed -n '1,120p' | while IFS= read -r line; do log "debug: ip link: $line"; done
	fi
	local i drv
	for i in /sys/class/net/*; do
		[ -d "$i" ] || continue
		i="${i##*/}"
		drv="$(readlink -f "/sys/class/net/$i/device/driver" 2>/dev/null)"
		[ -n "$drv" ] && log "debug: netif $i driver=$drv"
	done
}

ensure_qmi_cron() {
	local tmp

	tmp=$(mktemp /tmp/qmi-cron.XXXXXX) || {
		log "ERROR: mktemp for qmi cron failed"
		return 1
	}

	if crontab -l >/dev/null 2>&1; then
		crontab -l >"$tmp" 2>/dev/null || true
	else
		: >"$tmp"
	fi

	if ! grep -q "/usr/lib/matelex/qmi-failover" "$tmp"; then
		echo "*/15 * * * * /usr/lib/matelex/qmi-failover" >>"$tmp"
	fi

	if ! crontab "$tmp" 2>>"$LOG"; then
		log "ERROR: failed to install updated crontab for qmi-failover"
		rm -f "$tmp"
		return 1
	fi

	rm -f "$tmp"
	log "qmi-failover cron entry ensured via crontab"
}

# ---- Switch PPP→QMI only (called by nohup child to survive SSH disconnect) ----
do_switch_only() {
	log "=== PPP→QMI switch (background) started ==="
	log "Stopping quectel-ppp.service ..."
	systemctl stop quectel-ppp.service || true

	log "Restarting matelex-modem.service (modeminit) ..."
	systemctl restart matelex-modem.service || true

	log "Waiting for QMI device and net iface readiness (up to 90s each) ..."
	if ! wait_for_cdc_wdm0 90; then
		log "ERROR: /dev/cdc-wdm0 not ready after timeout"
		dump_net_snapshot
	else
		if ! wait_for_qmi_iface 90; then
			log "WARNING: QMI net iface not detected after timeout (will still try to start quectel-qmi)"
			dump_net_snapshot
		else
			log "QMI net iface detected: $(find_qmi_iface)"
		fi
	fi

	log "Starting quectel-qmi.service ..."
	systemctl start quectel-qmi.service || true
	log "=== PPP→QMI switch completed ==="
}

# ---- Deploy from /app/qmiPkg to system paths and configure systemd ----
do_deploy() {
	log "=== QMI deploy from $SRC_DIR ==="

	for f in quectel-qmi qmi-failover ppp-to-qmi-switch quectel-qmi.service qmi-logrotate; do
		if [ ! -f "$SRC_DIR/$f" ]; then
			log "ERROR: $SRC_DIR/$f not found"
			exit 1
		fi
	done

	mkdir -p /usr/lib/matelex 2>/dev/null || true

	install -m 755 "$SRC_DIR/quectel-qmi"       /usr/lib/matelex/quectel-qmi
	install -m 755 "$SRC_DIR/qmi-failover"     /usr/lib/matelex/qmi-failover
	install -m 755 "$SRC_DIR/ppp-to-qmi-switch" /usr/lib/matelex/ppp-to-qmi-switch
	install -m 644 "$SRC_DIR/quectel-qmi.service" /etc/systemd/system/quectel-qmi.service
	install -m 644 "$SRC_DIR/qmi-logrotate"    /etc/logrotate.d/qmi-logrotate

	if [ -f "$SRC_DIR/modeminit" ]; then
		install -m 755 "$SRC_DIR/modeminit" /usr/lib/matelex/modeminit
	fi

	log "Reloading systemd ..."
	systemctl daemon-reload

	log "Disabling and stopping quectel-ppp.service ..."
	systemctl disable quectel-ppp.service 2>/dev/null || true
	systemctl stop quectel-ppp.service 2>/dev/null || true

	log "Enabling quectel-qmi.service ..."
	systemctl enable quectel-qmi.service

	log "Ensuring qmi-failover cron entry via crontab"
	ensure_qmi_cron

	log "=== QMI deploy completed ==="
}

# ---- Main flow: first deploy, then run switch in background via nohup ----
run_deploy_then_switch() {
	do_deploy

	echo "Starting PPP→QMI switch in background (SSH may disconnect). Log: $LOG"
	nohup env LOG="$LOG" "$0" switch_only >> "$LOG" 2>&1 &
	echo "PID: $!"
	echo "To follow log: tail -f $LOG"
}

case "${1:-}" in
	switch_only)
		do_switch_only
		;;
	deploy)
		do_deploy
		;;
	"")
		run_deploy_then_switch
		;;
	*)
		echo "Usage: $0 [deploy]"
		echo "  (no args)  Deploy from $SRC_DIR and run PPP→QMI switch in background (nohup)"
		echo "  deploy    Only deploy files and enable QMI service; do not stop PPP"
		exit 1
		;;
esac

exit 0
