#!/bin/sh
# lib-score.sh — PURE per-metric + composite WAN scoring (ported from aiwanbal §2.3).
# No side effects: args in, single integer 0..100 on stdout.
# POSIX/ash-safe; integer/float math delegated to awk (available on OpenWrt).
#
# Scoring anchors (spec §2.3):
#   latency  5ms   -> 100 , 200ms -> 0
#   download 25    -> 100 , 0.5   -> 0   (MB/s)
#   upload   12.5  -> 100 , 0.5   -> 0   (MB/s)
#   jitter   1ms   -> 100 , 50ms  -> 0
#   loss     0%    -> 100 , 40%   -> 0
#   signal   -65   -> 100 , -95   -> 0   (dBm)

# clamp a numeric value to 0..100 and round half-up to an integer
_clamp() {
	awk -v v="$1" 'BEGIN{ if(v<0)v=0; if(v>100)v=100; printf "%d", (v+0.5) }'
}

# read one value from stdin and clamp/round it (pipe helper)
_pipeclamp() { read v; _clamp "$v"; }

score_latency()  { awk -v x="$1" 'BEGIN{ print 100*(200-x)/(200-5) }'    | _pipeclamp; }
score_download() { awk -v x="$1" 'BEGIN{ print 100*(x-0.5)/(25-0.5) }'   | _pipeclamp; }
score_upload()   { awk -v x="$1" 'BEGIN{ print 100*(x-0.5)/(12.5-0.5) }' | _pipeclamp; }
score_jitter()   { awk -v x="$1" 'BEGIN{ print 100*(50-x)/(50-1) }'      | _pipeclamp; }
score_loss()     { awk -v x="$1" 'BEGIN{ print 100*(40-x)/40 }'          | _pipeclamp; }
score_signal()   { awk -v x="$1" 'BEGIN{ print 100*(x-(-95))/((-65)-(-95)) }' | _pipeclamp; }

# Weighted 6-factor composite score.
# args: lat dl up jitter loss signal(optional)
# weights: latency35 dl25 up10 jit10 loss10 sig10.
# When signal is empty (no modem), its 10 points redistribute to latency(+5)
# and download(+5) so the remaining weights still total 100.
score_composite() {
	sl=$(score_latency "$1"); sd=$(score_download "$2"); su=$(score_upload "$3")
	sj=$(score_jitter "$4"); sp=$(score_loss "$5")
	if [ -n "$6" ]; then
		ss=$(score_signal "$6"); wsig=10; wlat=35; wdl=25
	else
		ss=0; wsig=0; wlat=40; wdl=30   # redistribute signal weight
	fi
	awk -v sl="$sl" -v sd="$sd" -v su="$su" -v sj="$sj" -v sp="$sp" -v ss="$ss" \
	    -v wlat="$wlat" -v wdl="$wdl" -v wsig="$wsig" 'BEGIN{
	    t=(sl*wlat + sd*wdl + su*10 + sj*10 + sp*10 + ss*wsig)/100
	    printf "%d",(t+0.5) }'
}

# Rolling average of N samples (integer, round half-up). Args: sample...
rolling_avg() {
	awk 'BEGIN{ n=ARGC-1; s=0; for(i=1;i<ARGC;i++) s+=ARGV[i]; printf "%d",(s/n+0.5) }' "$@"
}
