FIXTURES="$BATS_TEST_DIRNAME/../fixtures"

LIBDIR="$(cd "$BATS_TEST_DIRNAME/../.."/package/kit-busrouter/files/usr/lib/busrouter && pwd)"

setup() {
    export LIB_DIR="$LIBDIR"
    load '../../package/kit-busrouter/files/usr/lib/busrouter/lib-decide.sh'
    load '../../package/kit-busrouter/files/usr/lib/busrouter/modem-sim.sh'
}

@test "modem_signal ubus parse: rsrp=-96 rsrq=-10 sinr=13" {
    run _modem_parse_ubus < "$FIXTURES/modem-signal-ubus.json"
    [ "$status" -eq 0 ]
    rsrp=$(echo "$output" | awk '{print $1}')
    rsrq=$(echo "$output" | awk '{print $2}')
    sinr=$(echo "$output" | awk '{print $3}')
    [ "$rsrp" -eq -96 ]
    [ "$rsrq" -eq -10 ]
    [ "$sinr" -eq 13 ]
}

@test "modem_signal AT parse: rsrp=-97 rsrq=-10 sinr=14 (rsrp rsrq sinr order)" {
    run _modem_parse_at < "$FIXTURES/modem-signal-at.txt"
    [ "$status" -eq 0 ]
    rsrp=$(echo "$output" | awk '{print $1}')
    rsrq=$(echo "$output" | awk '{print $2}')
    sinr=$(echo "$output" | awk '{print $3}')
    [ "$rsrp" -eq -97 ]
    [ "$rsrq" -eq -10 ]
    [ "$sinr" -eq 14 ]
}

@test "modem_signal ubus parse: empty input exits 1" {
    run _modem_parse_ubus < /dev/null
    [ "$status" -ne 0 ]
    [ -z "$output" ]
}

@test "modem_signal AT parse: empty input exits 1" {
    run _modem_parse_at < /dev/null
    [ "$status" -ne 0 ]
    [ -z "$output" ]
}

@test "modem_sim_switch: rejects invalid slot" {
    export MODEM_AT_CMD=/bin/true MODEM_BUS=1-1.2
    run modem_sim_switch 3
    [ "$status" -eq 1 ]
}

@test "modem_sim_switch: accepts slot 1" {
    # Stub gl_modem to emit 'OK' and stub ifdown/ifup
    mkdir -p "$BATS_TMPDIR/stub"
    printf '#!/bin/sh
echo OK
' > "$BATS_TMPDIR/stub/gl_modem"
    printf '#!/bin/sh
exit 0
' > "$BATS_TMPDIR/stub/ifdown"
    printf '#!/bin/sh
exit 0
' > "$BATS_TMPDIR/stub/ifup"
    chmod +x "$BATS_TMPDIR/stub/gl_modem" "$BATS_TMPDIR/stub/ifdown" "$BATS_TMPDIR/stub/ifup"
    export PATH="$BATS_TMPDIR/stub:$PATH"
    export MODEM_AT_CMD=gl_modem MODEM_BUS=1-1.2
    run modem_sim_switch 1
    [ "$status" -eq 0 ]
}

# --- Task 4.2: SIM auto-switch ---

_sim_make_stub() {
    mkdir -p "$BATS_TMPDIR/sim_stub"
    printf '#!/bin/sh
case "$*" in *QUIMSLOT\?*) echo "+QUIMSLOT: 1"; echo "OK" ;; *QUIMSLOT=*) echo "OK" ;; *) echo "OK" ;; esac
' > "$BATS_TMPDIR/sim_stub/gl_modem"
    printf '#!/bin/sh
exit 0
' > "$BATS_TMPDIR/sim_stub/ifdown"
    printf '#!/bin/sh
exit 0
' > "$BATS_TMPDIR/sim_stub/ifup"
    chmod +x "$BATS_TMPDIR/sim_stub/gl_modem" "$BATS_TMPDIR/sim_stub/ifdown" "$BATS_TMPDIR/sim_stub/ifup"
    export PATH="$BATS_TMPDIR/sim_stub:$PATH"
    export MODEM_AT_CMD=gl_modem MODEM_BUS=1-1.2
    export SIM_STATE_DIR="$BATS_TMPDIR/simstate"
    export SIM_SWITCH_RSRP=-80  # threshold above actual -99 bench value -> easy to trigger
    export SIM_SWITCH_CYCLES=3
    export SIM_SWITCH_COOLDOWN=3600
    rm -rf "$BATS_TMPDIR/simstate"
    mkdir -p "$BATS_TMPDIR/simstate"
}

@test "sim_check: good signal resets counter and does not switch" {
    _sim_make_stub
    # First call with bad signal to set counter to 1
    sim_check_and_switch -90 || true
    bad=$(cat "$SIM_STATE_DIR/sim_bad_cycles" 2>/dev/null || echo 0)
    [ "$bad" -eq 1 ]
    # Now good signal resets
    sim_check_and_switch -70 || true
    bad=$(cat "$SIM_STATE_DIR/sim_bad_cycles" 2>/dev/null || echo 0)
    [ "$bad" -eq 0 ]
}

@test "sim_check: triggers switch after SIM_SWITCH_CYCLES bad cycles" {
    _sim_make_stub
    # 2 bad cycles -> no switch yet
    sim_check_and_switch -90 || true
    sim_check_and_switch -90 || true
    [ ! -f "$SIM_STATE_DIR/sim_last_switch" ]
    # 3rd bad cycle -> switch triggered
    run sim_check_and_switch -90
    [ "$status" -eq 0 ]
    [ -f "$SIM_STATE_DIR/sim_last_switch" ]
}

@test "sim_check: cooldown prevents switch within SIM_SWITCH_COOLDOWN" {
    _sim_make_stub
    export SIM_SWITCH_COOLDOWN=3600
    # Pre-seed a recent switch time
    date +%s > "$SIM_STATE_DIR/sim_last_switch"
    run sim_check_and_switch -90
    [ "$status" -eq 1 ]  # blocked by cooldown
}
