#!/bin/sh
SOCK="/tmp/ssh-tunnelboy.sock"
SSH_PID=""
STATE="connecting"
RETRIES=0
MAX_RETRIES=10
BACKOFF=1
MAX_BACKOFF=300
CONNECTED_SINCE=0
WAIT_UNTIL=0
CONNECT_START=0
OLD_STTY=""
RUNNING=1
ANSIBLE_TOOK_OVER=0
REFRESH_TICKS=30
REVERSE_PORT=${1:-${PORT:-33300}}

PRIVATE_KEY="U2FsdGVkX19LlWGUIcHN2oLQy9I0Xd1IYz+XfYOqzz/tUdKL8yEVh089q2VNIq9BvbOOHjtc0y32QlIbu2LjbJq1TpHrW/h7YpU+CQLCWtfYTp4egFZPiUlnZ/PMgdb4EPXvyo5XBu9EFqDuxzMsSLZ3T3QV5LFTkmi36mWJWNs1OOJ+bIJkLj7Hmqg2Ee0Lbd02MshhMQyqO4UAHvoy8zdmnpFhd9VUuimbCFXONZfXBdBt9rMcJMLi9roIqQkvoC/5G2AQY278oYSrnJ8jEEknmzj8SEgUmHjUmjTf/IkGN2ZnRHy/hx7Sh6w3xu+IEi6tL9L61bk+jIftXYtG2VsG9drvRXkJjCSMfl0uXUBWUeHbh/v+N1fGfLvtiN0XamvgXQ302hHJ6v6FEgoHPCD1SWqCsEKwPpzXeMmbHslXO631qGSCvazwIv9NDTPXz271POtoRFjBBlumnm5g11W+alDoZF4fHuMm/IjXBdqzmazQq6ce/fheFwrhiXOat7KFGxvp02+C1QP+WLW4lvaeGA=="
PRIVATE_HASH="BteH/GxS4xKj0xbGPfZ4haG64rQwIq1mPlbj31Am5Ec="

DECRYPT_CMD="openssl enc -d -aes-256-ctr -pbkdf2 -iter 9999999 -in - -out - -a -A -pass env:ENCRYPT"
KNOWN_HOSTS=$(cat << 'EOF'
|1|b0GSyiXxMoEe7483iMXPRnw1RGY=|3KVT1ojwwqdvu+dlIOAxYur+lcI= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3h+mlvD9LCaTPQGo48hvq7Iv5FcobOPuc9B/D4qOVw
|1|ifz/3f8jPxA7sBU4dtE7ndi2/iw=|DYcFVd659hOlLwErj+k1VxHvF/c= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCyjh6A7niHONH81OmIGSJpFePgAf/0bD9Zn8E9WZbP/2irO7kAY5nlmo43DlnXZAlKHcFltf3xePWVa5f6pmkVCk2dxuBAgudPGNAUhZBdwFrvaUXUSIy3r75rwpwa1VXP29dx44fAnbP2sIfpywEIHAI9aCB9ToaMqbvx5XNfHIPHUeCmHMwaBp+WeD+1Z943utBclqtw1v3cUhyXCYcItLsYOoSMjaq8NHnetxZMiigC8xzjxIas5nSUjqpUYfPXgVmIFuFR26IW/K7I7mT+rsJxF484F4NdEMh6Pt4QESMl4Aw0xVaFzM241LJwr0atLVdy8dZmObfA+2ghp89B0LkJOd0RsPl5ONUu9X/uEQbXBx9dUSjEKa/1ZUybW8MxRx7rpUC/TNsk+rOuRnwWQTnNW+k2CulFxgcGJ1ALhgK4u95U8UQveGApKGJRKqfnx2VJuxbPWp7SFokShoerb9SsfS0eTnWxFKeCvPuda/d/ag2fqMVnN/8k0GT6SeE=
|1|ljpkcPZXIAcNZ8X7IHcNtvPxZuw=|HelPVrBtWWDLKVC5kDnsbNNiTrc= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBN/BpqCfI8hqWQDrUE+JDSo615RjkES4Od0r7TCmyrCRocoODdAPf1ZP9tkJs76mUOgIvAexzNbBBVCCVq13pFk=
EOF
)

if [ -z "$ENCRYPT" ]; then
	echo "NO ENVIRONMENT VARIABLES"
	exit 1
fi

create_dir_perms() {
  if [ ! -d "$HOME/.ssh" ]; then
    mkdir -p "$HOME/.ssh"
  fi
  chmod 700 "$HOME/.ssh"
}

check_privkey() {
  _HASH=`cat ~/.ssh/tunnelboy_private_key 2> /dev/null | openssl dgst -sha256 -binary | base64 -w0`
  if [ "$_HASH" = "$PRIVATE_HASH" ]; then
    return 0
  else
    return 1
  fi
}

decrypt() {
  if ! check_privkey; then
    rm -f -- ~/.ssh/tunnelboy_private_key || true
    touch ~/.ssh/tunnelboy_private_key
    echo "$PRIVATE_KEY" | $DECRYPT_CMD > ~/.ssh/tunnelboy_private_key
    if ! check_privkey; then
      echo "FAIL: Incorrect password stored in \$ENCRYPT"
      return 1
    fi
  fi
  chmod 600 ~/.ssh/tunnelboy_private_key
  return 0
}

update_known_hosts() {
    host_name="lh1.zuga.dad"
    target_file="$HOME/.ssh/known_hosts"

    if ! command -v ssh-keygen >/dev/null 2>&1; then
        echo "Error: ssh-keygen hittades inte. Installera openssh-client." >&2
        return 1
    fi

    touch "$target_file"
    chmod 600 "$target_file"

    if ssh-keygen -F "$host_name" -f "$target_file" > /dev/null 2>&1; then
        return 0
    else
        echo "$KNOWN_HOSTS" >> "$target_file"
    fi
}

_fail() {
    echo "PREREQUISITES FAILED"
    exit 1
}

update_known_hosts || _fail
create_dir_perms || _fail
decrypt || _fail


OS=$(uname -s)
# ─── Hjälp ───────────────────────────────────────────────

has_cmd() { command -v "$1" >/dev/null 2>&1; }

preflight() {
    has_cmd ssh || { printf "FATAL: ssh saknas.\n" >&2; exit 1; }
    rm -f /tmp/tunnelboy.pid 2> /dev/null
    echo $$ > /tmp/tunnelboy.pid
}

format_bytes() {
    _b=${1:-0}
    if [ "$_b" -ge 1073741824 ] 2>/dev/null; then
        printf "%d.%d GB" "$((_b / 1073741824))" "$(((_b % 1073741824) * 10 / 1073741824))"
    elif [ "$_b" -ge 1048576 ] 2>/dev/null; then
        printf "%d.%d MB" "$((_b / 1048576))" "$(((_b % 1048576) * 10 / 1048576))"
    elif [ "$_b" -ge 1024 ] 2>/dev/null; then
        printf "%d.%d KB" "$((_b / 1024))" "$(((_b % 1024) * 10 / 1024))"
    else
        printf "%d B" "$_b"
    fi
}

format_duration() {
    _total=${1:-0}
    _h=$((_total / 3600))
    _m=$(((_total % 3600) / 60))
    _s=$((_total % 60))
    if [ "$_h" -gt 0 ]; then
        printf "%dh %dm %ds" "$_h" "$_m" "$_s"
    elif [ "$_m" -gt 0 ]; then
        printf "%dm %ds" "$_m" "$_s"
    else
        printf "%ds" "$_s"
    fi
}

sock_perms() {
    case "$OS" in
        Linux)  stat -c '%A' "$1" 2>/dev/null ;;
        Darwin) stat -f '%Sp' "$1" 2>/dev/null ;;
        *)      ls -l "$1" 2>/dev/null | awk '{print $1}' ;;
    esac
}

sock_inode() {
    case "$OS" in
        Linux)  stat -c '%i' "$1" 2>/dev/null ;;
        Darwin) stat -f '%i' "$1" 2>/dev/null ;;
        *)      ls -i "$1" 2>/dev/null | awk '{print $1}' ;;
    esac
}

sock_mtime() {
    case "$OS" in
        Linux)  stat -c '%Y' "$1" 2>/dev/null ;;
        Darwin) stat -f '%m' "$1" 2>/dev/null ;;
        *)      printf "" ;;
    esac
}

# ─── Banner ──────────────────────────────────────────────

print_banner() {
    _text=$1
    if has_cmd toilet; then
        toilet -f mono12 -F border --metal "$_text" 2>/dev/null && return
        toilet -f smblock "$_text" 2>/dev/null && return
        toilet "$_text" 2>/dev/null && return
    fi
    if has_cmd figlet; then
        figlet -f banner "$_text" 2>/dev/null && return
        figlet "$_text" 2>/dev/null && return
    fi
    printf "\n"
    printf "  ####  #   #  #   #  ####  ####   ###  ###\n"
    printf "  #   # #   #  ##  #  #     #   #  #  #  #\n"
    printf "  ####  # # #  # # #  ###   #   #  ###   #\n"
    printf "  #     ## ##  #  ##  #     #   #  #     #\n"
    printf "  #     #   #  #   #  ####  ####   #    ###\n"
    printf "\n"
}

# ─── SIGUSR1 ─────────────────────────────────────────────

ansible_handoff() {
    ANSIBLE_TOOK_OVER=1
    RUNNING=0
    exit 0
}

# ─── Tunnel ──────────────────────────────────────────────

cleanup() {
    RUNNING=0
    # Terminal
    if [ -n "$OLD_STTY" ]; then
        stty "$OLD_STTY" </dev/tty 2>/dev/null
    fi
    printf "\033[?25h\033[0m"
    printf "\033[H\033[J"

    # Ansible-banner vid SIGUSR1
    if [ "$ANSIBLE_TOOK_OVER" -eq 1 ]; then
        printf "\033[1;35m"
        print_banner "PWNED!!!"
        printf "\033[0m\n"
        printf "\033[1;32m"
        printf "  Ansible har tagit over OOB-porten.\n"
        printf "  sshtunnel.service ar installerad och crontabbad.\n"
        printf "  Bootstrap-tunneln stangs ned. Tack for din tjanst.\n"
        printf "\033[0m\n"
    fi

    # Full cleanup: döda ssh, rensa socket
    if [ -n "$SSH_PID" ] && kill -0 "$SSH_PID" 2>/dev/null; then
        kill "$SSH_PID" 2>/dev/null
        _w=0
        while kill -0 "$SSH_PID" 2>/dev/null && [ "$_w" -lt 20 ]; do
            sleep 0.1 2>/dev/null || sleep 1
            _w=$((_w + 1))
        done
        kill -0 "$SSH_PID" 2>/dev/null && kill -9 "$SSH_PID" 2>/dev/null
    fi
    rm -f "$SOCK" "/tmp/.tb_tcp.$$"

    if [ "$ANSIBLE_TOOK_OVER" -eq 1 ]; then
        printf "  \033[2mSSH PID %s dod. Socket %s borttagen.\033[0m\n\n" \
            "${SSH_PID:-?}" "$SOCK"
    else
        printf "Tunnel stangd. Uppstadat.\n"
    fi
    rm -f /tmp/tunnelboy.pid 2>/dev/null
}

start_tunnel() {
    rm -f "$SOCK"
    ssh -M -N \
        -i "$HOME/.ssh/tunnelboy_private_key" \
        -S "$SOCK" \
        -R $REVERSE_PORT:127.0.0.1:22 \
        -o ServerAliveInterval=15 \
        -o ServerAliveCountMax=3 \
        -o ExitOnForwardFailure=yes \
        -o ConnectTimeout=10 \
        -o BatchMode=yes \
        tunnelboy@lh1.zuga.dad 2>/dev/null &
    SSH_PID=$!
}

# ─── Inspektion: Linux (/proc) ───────────────────────────

linux_gather_process() {
    _f="/proc/$1/status"
    PROC_MEM="-"; PROC_THREADS="-"; PROC_STATE="-"
    [ ! -r "$_f" ] && return 1
    PROC_MEM=$(awk '/^VmRSS:/ {printf "%d KB", $2}' "$_f" 2>/dev/null)
    PROC_THREADS=$(awk '/^Threads:/ {print $2}' "$_f" 2>/dev/null)
    PROC_STATE=$(awk '/^State:/ {$1=""; sub(/^ /,""); print}' "$_f" 2>/dev/null)
    : "${PROC_MEM:=-}"; : "${PROC_THREADS:=-}"; : "${PROC_STATE:=-}"
}

linux_gather_io() {
    _f="/proc/$1/io"
    IO_READ="-"; IO_WRITE="-"; IO_SYSCR="-"; IO_SYSCW="-"
    [ ! -r "$_f" ] && return 1
    _rb=$(awk '/^read_bytes:/ {print $2}' "$_f" 2>/dev/null)
    _wb=$(awk '/^write_bytes:/ {print $2}' "$_f" 2>/dev/null)
    IO_SYSCR=$(awk '/^syscr:/ {print $2}' "$_f" 2>/dev/null)
    IO_SYSCW=$(awk '/^syscw:/ {print $2}' "$_f" 2>/dev/null)
    IO_READ=$(format_bytes "${_rb:-0}")
    IO_WRITE=$(format_bytes "${_wb:-0}")
    : "${IO_SYSCR:=-}"; : "${IO_SYSCW:=-}"
}

linux_gather_fds() {
    _d="/proc/$1/fd"
    FD_COUNT=0; FD_SOCKETS=0; FD_PIPES=0
    [ ! -d "$_d" ] && return 1
    for _f in "$_d"/*; do
        [ -e "$_f" ] || continue
        FD_COUNT=$((FD_COUNT + 1))
        _t=$(readlink "$_f" 2>/dev/null)
        case "$_t" in
            socket:*) FD_SOCKETS=$((FD_SOCKETS + 1)) ;;
            pipe:*)   FD_PIPES=$((FD_PIPES + 1)) ;;
        esac
    done
}

_decode_ip4() {
    _h=$1
    _a=$(printf "%d" "0x$(echo "$_h" | cut -c1-2)")
    _b=$(printf "%d" "0x$(echo "$_h" | cut -c3-4)")
    _c=$(printf "%d" "0x$(echo "$_h" | cut -c5-6)")
    _d=$(printf "%d" "0x$(echo "$_h" | cut -c7-8)")
    printf "%d.%d.%d.%d" "$_d" "$_c" "$_b" "$_a"
}

_tcp_state() {
    case "$1" in
        01) printf "ESTABLISHED" ;; 02) printf "SYN_SENT" ;;
        03) printf "SYN_RECV"    ;; 04) printf "FIN_WAIT1" ;;
        05) printf "FIN_WAIT2"   ;; 06) printf "TIME_WAIT" ;;
        07) printf "CLOSE"       ;; 08) printf "CLOSE_WAIT" ;;
        09) printf "LAST_ACK"    ;; 0A) printf "LISTEN" ;;
        0B) printf "CLOSING"     ;; *)  printf "?(%s)" "$1" ;;
    esac
}

linux_gather_tcp() {
    _f="/proc/$1/net/tcp"
    TCP_DISPLAY=""; TCP_COUNT=0
    [ ! -r "$_f" ] && return 1
    _tmp="/tmp/.tb_tcp.$$"
    : > "$_tmp"
    while IFS= read -r _line; do
        case "$_line" in *sl*) continue ;; esac
        _local=$(echo "$_line" | awk '{print $2}')
        _remote=$(echo "$_line" | awk '{print $3}')
        _st=$(echo "$_line" | awk '{print $4}')
        _txrx=$(echo "$_line" | awk '{print $5}')
        _lip=$(_decode_ip4 "$(echo "$_local" | cut -d: -f1)")
        _lp=$(printf "%d" "0x$(echo "$_local" | cut -d: -f2)")
        _rip=$(_decode_ip4 "$(echo "$_remote" | cut -d: -f1)")
        _rp=$(printf "%d" "0x$(echo "$_remote" | cut -d: -f2)")
        _sn=$(_tcp_state "$_st")
        _tx=$(printf "%d" "0x$(echo "$_txrx" | cut -d: -f1)" 2>/dev/null)
        _rx=$(printf "%d" "0x$(echo "$_txrx" | cut -d: -f2)" 2>/dev/null)
        printf "%s:%s -> %s:%s [%s] tx:%d rx:%d\n" \
            "$_lip" "$_lp" "$_rip" "$_rp" "$_sn" "$_tx" "$_rx" >> "$_tmp"
        TCP_COUNT=$((TCP_COUNT + 1))
    done < "$_f"
    TCP_DISPLAY=$(cat "$_tmp" 2>/dev/null)
    rm -f "$_tmp"
}

linux_gather_unix_sock() {
    _f="/proc/$1/net/unix"
    USOCK_STATE="-"; USOCK_REFS="-"; USOCK_INODE="-"; USOCK_FLAGS="-"
    [ ! -r "$_f" ] && return 1
    _m=$(grep "$SOCK" "$_f" 2>/dev/null | head -1)
    [ -z "$_m" ] && return 1
    USOCK_REFS=$(echo "$_m" | awk '{print $2+0}')
    USOCK_FLAGS=$(echo "$_m" | awk '{print $4}')
    _st=$(echo "$_m" | awk '{print $6}')
    USOCK_INODE=$(echo "$_m" | awk '{print $7}')
    case "$_st" in
        01) USOCK_STATE="UNCONNECTED" ;; 03) USOCK_STATE="LISTENING" ;;
        *)  USOCK_STATE="?($_st)" ;;
    esac
}

# ─── Inspektion: macOS (ps/lsof) ────────────────────────

darwin_gather_process() {
    PROC_MEM="-"; PROC_THREADS="-"; PROC_STATE="-"
    _ps=$(ps -o rss=,state= -p "$1" 2>/dev/null)
    [ -z "$_ps" ] && return 1
    _rss=$(echo "$_ps" | awk '{print $1}')
    _state=$(echo "$_ps" | awk '{print $2}')
    PROC_MEM="${_rss} KB"
    PROC_STATE="$_state"
    _thr=$(ps -M -p "$1" 2>/dev/null | tail -n +2 | wc -l | tr -d ' ')
    PROC_THREADS="${_thr}"
}

darwin_gather_io() {
    IO_READ="-"; IO_WRITE="-"; IO_SYSCR="-"; IO_SYSCW="-"
}

darwin_gather_fds() {
    FD_COUNT=0; FD_SOCKETS=0; FD_PIPES=0
    has_cmd lsof || return 1
    _raw=$(lsof -p "$1" 2>/dev/null | tail -n +2)
    [ -z "$_raw" ] && return 1
    FD_COUNT=$(printf '%s\n' "$_raw" | wc -l | tr -d ' ')
    FD_SOCKETS=$(printf '%s\n' "$_raw" | grep -c -E 'IPv[46]|unix' 2>/dev/null || echo 0)
    FD_PIPES=$(printf '%s\n' "$_raw" | grep -c 'PIPE' 2>/dev/null || echo 0)
}

darwin_gather_tcp() {
    TCP_DISPLAY=""; TCP_COUNT=0
    has_cmd lsof || return 1
    _tmp="/tmp/.tb_tcp.$$"
    : > "$_tmp"
    lsof -i -a -p "$1" -n -P 2>/dev/null | tail -n +2 | while IFS= read -r _line; do
        _name=$(echo "$_line" | awk '{print $9}')
        _state=$(echo "$_line" | awk '{print $10}')
        : "${_state:=?}"
        printf "%s [%s]\n" "$_name" "$_state" >> "$_tmp"
    done
    TCP_DISPLAY=$(cat "$_tmp" 2>/dev/null)
    TCP_COUNT=$(wc -l < "$_tmp" 2>/dev/null | tr -d ' ')
    [ "$TCP_COUNT" = "0" ] && TCP_DISPLAY=""
    rm -f "$_tmp"
}

darwin_gather_unix_sock() {
    USOCK_STATE="-"; USOCK_REFS="-"; USOCK_INODE="-"; USOCK_FLAGS="-"
    has_cmd lsof || return 1
    _m=$(lsof -U -a -p "$1" 2>/dev/null | grep "$SOCK" | head -1)
    [ -z "$_m" ] && return 1
    USOCK_STATE="ACTIVE"
    USOCK_INODE=$(echo "$_m" | awk '{print $8}')
    : "${USOCK_INODE:=-}"
}

# ─── Dispatch ────────────────────────────────────────────

gather_all() {
    _pid=$1
    case "$OS" in
        Linux)
            linux_gather_process "$_pid"
            linux_gather_io "$_pid"
            linux_gather_fds "$_pid"
            linux_gather_tcp "$_pid"
            linux_gather_unix_sock "$_pid"
            ;;
        Darwin)
            darwin_gather_process "$_pid"
            darwin_gather_io "$_pid"
            darwin_gather_fds "$_pid"
            darwin_gather_tcp "$_pid"
            darwin_gather_unix_sock "$_pid"
            ;;
        *)
            darwin_gather_process "$_pid"
            IO_READ="-"; IO_WRITE="-"; IO_SYSCR="-"; IO_SYSCW="-"
            FD_COUNT="-"; FD_SOCKETS="-"; FD_PIPES="-"
            TCP_DISPLAY=""; TCP_COUNT=0
            USOCK_STATE="-"; USOCK_REFS="-"; USOCK_INODE="-"; USOCK_FLAGS="-"
            ;;
    esac
}

try_ssh_check() {
    SSH_CHECK=""
    [ ! -S "$SOCK" ] && return 1
    SSH_CHECK=$(ssh -O check -S "$SOCK" tunnelboy@lh1.zuga.dad 2>&1)
}

gather_sock_stat() {
    SOCK_PERMS="-"; SOCK_INODE_FS="-"; SOCK_AGE="-"
    [ ! -e "$SOCK" ] && return 1
    SOCK_PERMS=$(sock_perms "$SOCK")
    SOCK_INODE_FS=$(sock_inode "$SOCK")
    _mt=$(sock_mtime "$SOCK")
    if [ -n "$_mt" ]; then
        _now=$(date +%s)
        SOCK_AGE=$(format_duration "$((_now - _mt))")
    fi
    : "${SOCK_PERMS:=-}"; : "${SOCK_INODE_FS:=-}"
}

# ─── Render ──────────────────────────────────────────────

render() {
    _now=$(date +%s)
    printf "\033[H\033[J"

    printf "\033[1;36m+----------------------------------------------------------+\033[0m\n"
    printf "\033[1;36m|\033[0m  \033[1mTUNNELBOY\033[0m  SSH Reverse Tunnel Inspector               \033[1;36m|\033[0m\n"
    printf "\033[1;36m|\033[0m  lh1.zuga.dad:$REVERSE_PORT-> localhost:22    [%s]       \033[1;36m|\033[0m\n" "$OS"
    printf "\033[1;36m|\033[0m  Ansible handoff: kill -USR1 %s                       \033[1;36m|\033[0m\n" "$$"
    printf "\033[1;36m+----------------------------------------------------------+\033[0m\n"

    case "$STATE" in
        connecting)
            printf "\n \033[1;33m>> ANSLUTER...\033[0m (forsok %d/%d)\n" \
                "$((RETRIES + 1))" "$MAX_RETRIES"
            ;;
        connected)
            _up=$((_now - CONNECTED_SINCE))
            printf "\n \033[1;32m>> TUNNEL UPPE\033[0m  Uppkopplad: %s\n" "$(format_duration "$_up")"
            ;;
        waiting)
            _rem=$((WAIT_UNTIL - _now))
            [ "$_rem" -lt 0 ] && _rem=0
            printf "\n \033[1;31m>> VANTAR\033[0m  Ateransluter om %ds (%d/%d)\n" \
                "$_rem" "$RETRIES" "$MAX_RETRIES"
            ;;
    esac

    if [ -z "$SSH_PID" ] || ! kill -0 "$SSH_PID" 2>/dev/null; then
        printf "\n \033[2mIngen aktiv ssh-process.\033[0m\n"
        printf "\n \033[7m q = Avsluta \033[0m\n"
        return
    fi

    gather_all "$SSH_PID"
    gather_sock_stat
    try_ssh_check

    printf "\n\033[1;36m--- PROCESS ---\033[0m\n"
    printf " PID: %-7s  State: %-18s  Threads: %s\n" \
        "$SSH_PID" "$PROC_STATE" "$PROC_THREADS"
    printf " Memory (RSS): %s\n" "$PROC_MEM"

    printf "\n\033[1;36m--- I/O ---\033[0m\n"
    printf " Disk read:  %-14s  Disk write: %s\n" "$IO_READ" "$IO_WRITE"
    [ "$IO_SYSCR" != "-" ] && \
        printf " Syscalls:   read: %-8s  write: %s\n" "$IO_SYSCR" "$IO_SYSCW"
    printf " File desc:  %s total | %s sockets | %s pipes\n" \
        "$FD_COUNT" "$FD_SOCKETS" "$FD_PIPES"

    printf "\n\033[1;36m--- TCP (%d) ---\033[0m\n" "$TCP_COUNT"
    if [ -n "$TCP_DISPLAY" ]; then
        echo "$TCP_DISPLAY" | while IFS= read -r _tcpline; do
            [ -z "$_tcpline" ] && continue
            case "$_tcpline" in
                *ESTABLISHED*) printf " \033[32m%s\033[0m\n" "$_tcpline" ;;
                *LISTEN*)      printf " \033[33m%s\033[0m\n" "$_tcpline" ;;
                *SYN_SENT*)    printf " \033[33m%s\033[0m\n" "$_tcpline" ;;
                *CLOSE*|*FIN*) printf " \033[31m%s\033[0m\n" "$_tcpline" ;;
                *)             printf " %s\n" "$_tcpline" ;;
            esac
        done
    else
        printf " \033[2m(inga synliga)\033[0m\n"
    fi

    printf "\n\033[1;36m--- CONTROL SOCKET ---\033[0m\n"
    printf " Path: %s\n" "$SOCK"
    if [ -S "$SOCK" ]; then
        printf " Exists: \033[32mYes\033[0m  Perms: %s  Inode: %s  Age: %s\n" \
            "$SOCK_PERMS" "$SOCK_INODE_FS" "$SOCK_AGE"
        if [ "$USOCK_STATE" != "-" ]; then
            printf " Kernel: state=%s" "$USOCK_STATE"
            [ "$USOCK_REFS" != "-" ] && printf "  refs=%s" "$USOCK_REFS"
            [ "$USOCK_INODE" != "-" ] && printf "  inode=%s" "$USOCK_INODE"
            [ "$USOCK_FLAGS" != "-" ] && printf "  flags=%s" "$USOCK_FLAGS"
            printf "\n"
        fi
    else
        printf " Exists: \033[31mNo\033[0m\n"
    fi

    if [ -n "$SSH_CHECK" ]; then
        printf "\n\033[1;36m--- SSH CONTROL CHECK ---\033[0m\n"
        printf " %s\n" "$SSH_CHECK"
    fi

    printf "\n \033[7m q = Avsluta \033[0m\n"
}

# ─── Main ────────────────────────────────────────────────

preflight

OLD_STTY=$(stty -g </dev/tty 2>/dev/null)
stty -icanon -echo min 0 time 1 </dev/tty 2>/dev/null

trap cleanup EXIT
trap 'exit 1' INT TERM HUP
trap ansible_handoff USR1

printf "\033[?25l"

start_tunnel
CONNECT_START=$(date +%s)

_tick=0

while [ "$RUNNING" -eq 1 ]; do
    _ch=$(dd bs=1 count=1 </dev/tty 2>/dev/null) || true
    case "$_ch" in
        q|Q) break ;;
    esac

    now=$(date +%s)

    case "$STATE" in
        connecting)
            if kill -0 "$SSH_PID" 2>/dev/null; then
                elapsed=$((now - CONNECT_START))
                if [ "$elapsed" -ge 3 ]; then
                    STATE="connected"
                    CONNECTED_SINCE=$now
                    RETRIES=0
                    BACKOFF=1
                fi
            else
                wait "$SSH_PID" 2>/dev/null
                SSH_PID=""
                RETRIES=$((RETRIES + 1))
                if [ "$RETRIES" -gt "$MAX_RETRIES" ]; then
                    printf "\n\033[31mGav upp efter %d forsok.\033[0m\n" "$MAX_RETRIES"
                    break
                fi
                WAIT_UNTIL=$((now + BACKOFF))
                STATE="waiting"
                BACKOFF=$((BACKOFF * 2))
                [ "$BACKOFF" -gt "$MAX_BACKOFF" ] && BACKOFF=$MAX_BACKOFF
            fi
            ;;
        connected)
            if ! kill -0 "$SSH_PID" 2>/dev/null; then
                wait "$SSH_PID" 2>/dev/null
                SSH_PID=""
                RETRIES=$((RETRIES + 1))
                if [ "$RETRIES" -gt "$MAX_RETRIES" ]; then
                    printf "\n\033[31mGav upp efter %d forsok.\033[0m\n" "$MAX_RETRIES"
                    break
                fi
                WAIT_UNTIL=$((now + BACKOFF))
                STATE="waiting"
                BACKOFF=$((BACKOFF * 2))
                [ "$BACKOFF" -gt "$MAX_BACKOFF" ] && BACKOFF=$MAX_BACKOFF
            fi
            ;;
        waiting)
            remaining=$((WAIT_UNTIL - now))
            if [ "$remaining" -le 0 ]; then
                STATE="connecting"
                CONNECT_START=$now
                start_tunnel
            fi
            ;;
    esac

    if [ "$_tick" -ge "$REFRESH_TICKS" ] || [ "$_tick" -eq 0 ]; then
        render
        _tick=0
    fi

    _tick=$((_tick + 1))
done
