#!/bin/sh /etc/rc.common

START=99
STOP=10

# Глобальные константы (без вычислений и вывода)
SOCKS_PORT=2080
REDIR_PORT=12300
PIDFILE="/var/run/ipt2socks.pid"
LOGTAG="xray-proxy"
CONFIG_FILE="/root/config.json"
XRAY_URL="http://f.n1kt.ru/xray"
IPT2SOCKS_URL="http://f.n1kt.ru/ipt2socks"
MIN_SPACE_KB=25600

log() {
    logger -t "$LOGTAG" "$1"
    echo "[$(date '+%H:%M:%S')] $1"
}

has_internet() {
    for host in "1.1.1.1" "8.8.8.8" "ipv6.google.com"; do
        ping -c 1 -W 2 "$host" >/dev/null 2>&1 && return 0
    done
    return 1
}

is_socks_up() {
    if command -v nc >/dev/null 2>&1; then
        printf "GET / HTTP/1.0\r\n\r\n" | nc -w 2 127.0.0.1 "$SOCKS_PORT" >/dev/null 2>&1 && return 0
    fi
    (echo >/dev/tcp/127.0.0.1/"$SOCKS_PORT") >/dev/null 2>&1 && return 0
    return 1
}

download_with_curl() {
    local url="$1" output="$2" name="$3" attempt=1 max_attempts=3
    log "Downloading $name from $url..."
    while [ $attempt -le $max_attempts ]; do
        log "  Attempt $attempt/$max_attempts..."
        if curl -L --limit-rate 300k -f -s -S --connect-timeout 20 --max-time 120 "$url" -o "$output" 2>/dev/null; then
            [ -s "$output" ] && chmod +x "$output" && { log "  ✓ $name downloaded"; return 0; }
        fi
        attempt=$((attempt + 1))
        sleep 2
        rm -f "$output" 2>/dev/null
    done
    log "  ✗ Failed to download $name"
    return 1
}

verify_binary() {
    [ -x "$1" ] || return 1
    head -c 4 "$1" 2>/dev/null | grep -q $'\x7fELF' && return 0
    log "Warning: $2 may not be a valid ELF, but is executable"
    return 0
}

get_bin_path() {
    if [ -x "/usr/bin/xray" ] && [ -x "/usr/bin/ipt2socks" ]; then
        echo "/usr/bin"
        return
    fi
    local free_flash=$(df -k / 2>/dev/null | awk 'NR==2 {print $4}')
    local free_tmp=$(df -k /tmp 2>/dev/null | awk 'NR==2 {print $4}')
    if [ "${free_flash:-0}" -ge "$MIN_SPACE_KB" ]; then
        echo "/usr/bin"
    elif [ "${free_tmp:-0}" -ge "$MIN_SPACE_KB" ]; then
        echo "/tmp"
    else
        echo "/tmp"
    fi
}

start() {
    log "=== Starting xray-proxy ==="
    local BIN_PATH=$(get_bin_path)
    local XRAY_BIN="$BIN_PATH/xray"
    local IPT2SOCKS_BIN="$BIN_PATH/ipt2socks"
    
    [ "$BIN_PATH" = "/usr/bin" ] && log "Using persistent /usr/bin" || log "Using volatile /tmp"

    log "Waiting for network..."
    local wait=0
    while ! has_internet && [ $wait -lt 60 ]; do sleep 2; wait=$((wait + 1)); done
    if ! has_internet; then log "⚠ No internet. Skipping."; return 0; fi

    [ ! -x "$XRAY_BIN" ] && { download_with_curl "$XRAY_URL" "$XRAY_BIN" "xray" || return 0; }
    [ ! -x "$IPT2SOCKS_BIN" ] && { download_with_curl "$IPT2SOCKS_URL" "$IPT2SOCKS_BIN" "ipt2socks" || return 0; }

    if ! is_socks_up; then
        log "Starting xray..."
        killall -9 xray 2>/dev/null
        $XRAY_BIN run -c "$CONFIG_FILE" >/tmp/xray.log 2>&1 &
        local pid=$!
        sleep 3
        if ! kill -0 "$pid" 2>/dev/null; then
            log "⚠ xray crashed (code $?). Log:"
            [ -s /tmp/xray.log ] && tail -n 5 /tmp/xray.log | while read l; do log "  $l"; done
            return 0
        fi
        log "xray started (PID: $pid)"
    else
        log "SOCKS already running"
    fi

    log "Starting ipt2socks..."
    killall -9 ipt2socks 2>/dev/null
    $IPT2SOCKS_BIN -b 0.0.0.0 -l "$REDIR_PORT" -s 127.0.0.1 -p "$SOCKS_PORT" -R -c 256 >/tmp/ipt2socks.log 2>&1 &
    local pid2=$!
    sleep 2
    if kill -0 "$pid2" 2>/dev/null; then
        echo "$pid2" > "$PIDFILE"
        log "ipt2socks started (PID: $pid2)"
    else
        log "⚠ ipt2socks failed"
        return 0
    fi

    log "Applying nftables..."
    nft delete table inet transparent_proxy 2>/dev/null
    nft add table inet transparent_proxy || { log "ERROR: nft table"; return 1; }
    nft add chain inet transparent_proxy prerouting { type nat hook prerouting priority -100\; }
    nft add rule inet transparent_proxy prerouting ip daddr { 192.168.0.0/16, 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12 } return
    nft add rule inet transparent_proxy prerouting tcp dport { 80, 443 } redirect to "$REDIR_PORT"
    log "✓ nftables applied"
}

stop() {
    log "=== Stopping xray-proxy ==="
    nft delete table inet transparent_proxy 2>/dev/null
    [ -f "$PIDFILE" ] && { kill "$(cat "$PIDFILE" 2>/dev/null)" 2>/dev/null; rm -f "$PIDFILE"; }
    killall -9 ipt2socks xray 2>/dev/null
    log "Stopped"
}

restart() { stop; sleep 2; start; }
boot() { sleep 10; start; }
