#!/bin/bash

QMI_FAILOVER_CRON_LINE="*/15 * * * * /usr/lib/matelex/qmi-failover"

ensure_qmi_failover_cron()
{
	local tmp

	tmp=$(mktemp /tmp/qmi-cron.XXXXXX) || {
		log_qmi "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 "$QMI_FAILOVER_CRON_LINE" >>"$tmp"
	fi

	if ! crontab "$tmp" >>"$QMI_LOG" 2>&1; then
		log_qmi "ERROR: failed to install updated crontab (ensure qmi-failover)"
		rm -f "$tmp"
		return 1
	fi

	rm -f "$tmp"
	return 0
}

# Quectel EG21 Modem in QMI mode. Only use wwan* (e.g. wwan0); log if wwx* appears.
QMI_LOG_DIR="/app/qmi-log"
QMI_LOG="$QMI_LOG_DIR/quectel-qmi.log"
mkdir -p "$QMI_LOG_DIR" 2>/dev/null || true
log_qmi() { echo "$(date -Iseconds) $*" >> "$QMI_LOG"; }

dump_net_snapshot()
{
	log_qmi "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 | while IFS= read -r line; do
			log_qmi "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_qmi "debug: netif $i driver=$drv"
	done
}

# Find a real QMI net interface by sysfs capability, not by name.
# A QMI interface exposes: /sys/class/net/<iface>/qmi/raw_ip
find_qmi_iface()
{
	local w n

	# Prefer wwan* naming if it is a QMI interface.
	for w in /sys/class/net/wwan*; do
		[ -d "$w" ] || continue
		n="${w##*/}"
		[ -f "/sys/class/net/$n/qmi/raw_ip" ] && echo "$n" && return 0
	done

	# Fallback: any interface exposing qmi/raw_ip.
	for w in /sys/class/net/*; do
		[ -d "$w" ] || continue
		n="${w##*/}"
		[ -f "/sys/class/net/$n/qmi/raw_ip" ] && echo "$n" && return 0
	done

	return 1
}

qmi_start()
{
	set -e
	local dev="/dev/cdc-wdm0"
	local wait=90

	log_qmi "=== quectel-qmi start requested ==="

	# Wait for QMI device
	while [ ! -c "$dev" ] && [ $wait -gt 0 ]; do
		echo "Waiting for $dev ... ($wait s)"
		log_qmi "waiting for $dev ... ($wait s)"
		sleep 2
		wait=$((wait - 2))
	done
	if [ ! -c "$dev" ]; then
		echo "Error: $dev not found"
		log_qmi "ERROR: $dev not found, aborting start"
		exit 1
	fi

	echo -1 >/sys/module/usbcore/parameters/autosuspend
	log_qmi "setting modem online via qmicli dms-set-operating-mode"
	/usr/bin/qmicli -d "$dev" --dms-set-operating-mode='online'

	# Start network first; then wait for wwan*
	log_qmi "starting network: apn='internet.swir', ip-type=4"
	/usr/bin/qmicli -p -d "$dev" --device-open-net='net-raw-ip|net-no-qos-header' --wds-start-network="apn='internet.swir',ip-type=4" --client-no-release-cid

	QMI_IFACE=""
	wait=90
	while [ $wait -gt 0 ]; do
		QMI_IFACE=$(find_qmi_iface) && break
		echo "Waiting for QMI interface (qmi/raw_ip) ... ($wait s)"
		log_qmi "waiting for QMI interface (qmi/raw_ip) ... ($wait s)"
		sleep 2
		wait=$((wait - 2))
	done
	if [ -z "$QMI_IFACE" ]; then
		for w in /sys/class/net/wwx*; do
			[ -d "$w" ] || continue
			log_qmi "no wwan* found; wwx* present: ${w##*/} (only wwan* supported)"
			break
		done
		echo "Error: no wwan* interface found. Check: ls /sys/class/net/ ; ip link"
		log_qmi "ERROR: no wwan* interface found, giving up"
		dump_net_snapshot
		exit 1
	fi
	echo "Using interface: $QMI_IFACE"
	log_qmi "using interface: $QMI_IFACE"

	set +e
	log_qmi "setting autoconnect settings (enabled, home-only)"
	/usr/bin/qmicli -d "$dev" --wds-set-autoconnect-settings=enabled,home-only >> "$QMI_LOG" 2>&1 || true
	set -e

	log_qmi "configuring raw_ip and bringing interface up"
	/usr/sbin/ifconfig "$QMI_IFACE" down 2>/dev/null || true
	echo 'Y' | tee /sys/class/net/"$QMI_IFACE"/qmi/raw_ip >> "$QMI_LOG" 2>&1
	/usr/sbin/ifconfig "$QMI_IFACE" up
	/usr/sbin/ip link set dev "$QMI_IFACE" mtu 1400 >> "$QMI_LOG" 2>&1
	log_qmi "starting udhcpc on $QMI_IFACE"
	/usr/sbin/udhcpc -i "$QMI_IFACE" >> "$QMI_LOG" 2>&1

	set +e
	ensure_qmi_failover_cron && log_qmi "cron entry for qmi-failover ensured via crontab" || log_qmi "WARNING: failed to ensure qmi-failover cron entry"
	log_qmi "=== quectel-qmi start completed ==="
}

# Stop QMI/wwan0
qmi_stop()
{
	echo "Stop QMI Modem link"
	log_qmi "=== quectel-qmi stop requested ==="
	log_qmi "leaving qmi-failover cron entry intact (self-heal should remain enabled)"
	/usr/bin/qmi-network /dev/cdc-wdm0 stop >> "$QMI_LOG" 2>&1
	IFACE=$(find_qmi_iface) && /usr/sbin/ifconfig "$IFACE" down 2>/dev/null || true
	log_qmi "stopped, interface brought down (if present)"
}

# Status QMI/wwan0
qmi_status()
{
	/usr/bin/qmi-network /dev/cdc-wdm0 status
}

###########################
#  Execution starts here  #
###########################
case $1 in
start)
        qmi_start
        ;;
stop)
        qmi_stop
        ;;
status)
        qmi_status
        ;; 
esac

exit 0