# SOCKS5-туннель для Cursor (обход PING timeout из РФ).
# Использование: .\cursor-socks-tunnel.ps1 [start|stop|status]
# См. docs/cursor/README.md и docs/connectivity/WINDOWS_CURSOR_TUNNEL.md

param(
    [Parameter(Position = 0)]
    [ValidateSet("start", "stop", "status")]
    [string]$Command = "start"
)

$CURSOR_SOCKS_PORT = if ($env:CURSOR_SOCKS_PORT) { $env:CURSOR_SOCKS_PORT } else { "10809" }
$SSH_HOST = if ($env:CURSOR_TUNNEL_HOST) { $env:CURSOR_TUNNEL_HOST } else { "ahau@149.154.64.19" }
$CursorViaDo = ($env:CURSOR_SOCKS_VIA_DO -ne "0")

function Test-PortListening {
    $conn = Get-NetTCPConnection -LocalPort $CURSOR_SOCKS_PORT -State Listen -ErrorAction SilentlyContinue
    return $null -ne $conn
}

function Get-SshTunnelPids {
    # Найти процессы ssh.exe, у которых в командной строке есть -D и наш порт
    Get-CimInstance Win32_Process -Filter "Name = 'ssh.exe'" -ErrorAction SilentlyContinue |
        Where-Object { $_.CommandLine -match "-D\s+$CURSOR_SOCKS_PORT" } |
        ForEach-Object { $_.ProcessId }
}

function Start-Tunnel {
    if (Test-PortListening) {
        Write-Host "SOCKS already listening on 127.0.0.1:$CURSOR_SOCKS_PORT"
        return
    }
    $targetHost = $SSH_HOST
    $stableOpts = @(
        "-o", "TCPKeepAlive=yes",
        "-o", "IPQoS=throughput",
        "-o", "ServerAliveInterval=60",
        "-o", "ServerAliveCountMax=4"
    )
    $ruOpts = @(
        "-o", "ServerAliveInterval=30",
        "-o", "ServerAliveCountMax=6"
    )
    if ($CursorViaDo) {
        & ssh -o BatchMode=yes -o ConnectTimeout=6 -o ConnectionAttempts=1 hsites-ahau "exit 0" 2>$null
        if ($LASTEXITCODE -ne 0) {
            Write-Error "hsites-ahau недоступен: SOCKS только по цепочке Mac→RU→DO (без прямого Mac→DO). Восстановите SSH до RU или задайте CURSOR_SOCKS_VIA_DO=0."
            exit 1
        }
        $targetHost = "telegram-socks-via-do"
    }
    $sshArgs = @(
        "-D", $CURSOR_SOCKS_PORT,
        "-f", "-N"
    )
    if ($CursorViaDo) {
        $sshArgs += $stableOpts
    } else {
        $sshArgs += $ruOpts
    }
    $sshArgs += $targetHost
    & ssh @sshArgs
    if ($LASTEXITCODE -eq 0) {
        if ($CursorViaDo) {
            Write-Host "SOCKS tunnel started: 127.0.0.1:$CURSOR_SOCKS_PORT -> $targetHost (DO exit)"
        } else {
            Write-Host "SOCKS tunnel started: 127.0.0.1:$CURSOR_SOCKS_PORT -> $targetHost (RU exit, CURSOR_SOCKS_VIA_DO=0)"
        }
    } else {
        Write-Error "Failed to start tunnel (exit code $LASTEXITCODE). Check SSH config (telegram-socks-via-do) or host: $targetHost"
        exit $LASTEXITCODE
    }
}

function Stop-Tunnel {
    $pids = Get-SshTunnelPids
    if ($pids) {
        foreach ($pid in $pids) {
            Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue
        }
        Write-Host "Tunnel stopped (killed SSH process(es): $($pids -join ', '))."
    } else {
        # Fallback: убить процесс, занимающий порт 10809
        $conn = Get-NetTCPConnection -LocalPort $CURSOR_SOCKS_PORT -State Listen -ErrorAction SilentlyContinue
        if ($conn) {
            $conn | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }
            Write-Host "Tunnel stopped (killed process on port $CURSOR_SOCKS_PORT)."
        } else {
            Write-Host "No SOCKS tunnel found on port $CURSOR_SOCKS_PORT."
        }
    }
}

function Get-Status {
    if (Test-PortListening) {
        Write-Host "SOCKS listening on 127.0.0.1:$CURSOR_SOCKS_PORT"
        Get-NetTCPConnection -LocalPort $CURSOR_SOCKS_PORT -State Listen -ErrorAction SilentlyContinue |
            Format-Table LocalAddress, LocalPort, State, OwningProcess -AutoSize
    } else {
        Write-Host "No SOCKS listener on port $CURSOR_SOCKS_PORT"
    }
}

switch ($Command) {
    "start"  { Start-Tunnel }
    "stop"   { Stop-Tunnel }
    "status" { Get-Status }
}
