@echo off
setlocal EnableExtensions
chcp 65001 >nul
title Reset Completo da Rede

:: ============================================================================
::  ResetRede.bat
::  Faz backup da configuração atual, limpa caches, redefine TCP/IP e Winsock,
::  reinicia apenas os adaptadores físicos que estavam ativos, renova o DHCP e
::  testa a conectividade no final.
::
::  Uso:
::    ResetRede.bat              -> modo interativo
::    ResetRede.bat /s           -> silencioso (sem perguntas nem pausas)
::    ResetRede.bat /s /forcar   -> silencioso e redefine TCP/IP mesmo com IP fixo
::    ResetRede.bat /r           -> reinicia o computador automaticamente no fim
::
::  Códigos de saída:
::    0 = concluído, conectividade OK
::    1 = sem privilégios de administrador / UAC negado
::    2 = concluído, mas houve falha em algum comando de reset
::    3 = concluído, mas a conectividade não foi confirmada
::        (normal em alguns casos até reiniciar o computador)
::
::  Logs e backups: %ProgramData%\ResetRede\
:: ============================================================================

:: ---------------------------------------------------------------- Parâmetros
set "SILENCIOSO=0"
set "FORCAR=0"
set "REINICIAR=0"
for %%P in (%*) do (
    if /i "%%~P"=="/s"          set "SILENCIOSO=1"
    if /i "%%~P"=="/silencioso" set "SILENCIOSO=1"
    if /i "%%~P"=="/forcar"     set "FORCAR=1"
    if /i "%%~P"=="/r"          set "REINICIAR=1"
    if /i "%%~P"=="/reiniciar"  set "REINICIAR=1"
)

:: ---------------------------------------------------------------- Cores ANSI
for /f %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
set "C_RST=%ESC%[0m"
set "C_TIT=%ESC%[96m"
set "C_OK=%ESC%[92m"
set "C_AVS=%ESC%[93m"
set "C_ERR=%ESC%[91m"
set "C_DIM=%ESC%[90m"

:: ------------------------------------------------- Verificação de privilégio
fltmc >nul 2>&1
if errorlevel 1 goto :elevar
goto :inicio

:elevar
if /i "%~1"=="__elevado" (
    echo %C_ERR%[ERRO]%C_RST% Não foi possível obter privilégios de administrador.
    if "%SILENCIOSO%"=="0" pause
    exit /b 1
)
echo.
echo %C_AVS%Solicitando privilégios de administrador (UAC)...%C_RST%
powershell -NoProfile -ExecutionPolicy Bypass -Command "try { Start-Process -FilePath '%~f0' -ArgumentList '__elevado %*' -Verb RunAs -ErrorAction Stop; exit 0 } catch { exit 1 }"
if errorlevel 1 (
    echo %C_ERR%[ERRO]%C_RST% Elevação cancelada pelo usuário ou bloqueada pela política.
    if "%SILENCIOSO%"=="0" pause
    exit /b 1
)
exit /b 0

:: ============================================================================
:inicio
cd /d "%~dp0"
set "RC=0"
set "FALHAS=0"
set "PULAR_IP=0"

:: ---------------------------------------------------------------- Log
for /f %%t in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMdd_HHmmss"') do set "STAMP=%%t"
set "LOGDIR=%ProgramData%\ResetRede"
if not exist "%LOGDIR%" mkdir "%LOGDIR%" >nul 2>&1
set "LOG=%LOGDIR%\reset_rede.log"
set "BKP_IPCONFIG=%LOGDIR%\backup_ipconfig_%STAMP%.txt"
set "BKP_DUMP=%LOGDIR%\backup_netsh_%STAMP%.txt"
call :log "================ INÍCIO (usuário: %USERNAME% / máquina: %COMPUTERNAME%) ================"

cls
echo.
echo %C_TIT%  ╔══════════════════════════════════════════════════════════╗%C_RST%
echo %C_TIT%  ║               RESET COMPLETO DA REDE                     ║%C_RST%
echo %C_TIT%  ╚══════════════════════════════════════════════════════════╝%C_RST%
echo %C_DIM%   Máquina: %COMPUTERNAME%   ^|   Logs: %LOGDIR%%C_RST%
echo.
echo %C_AVS%   Atenção: a conexão vai cair por alguns segundos.%C_RST%
echo %C_AVS%   Se estiver via acesso remoto (RDP/AnyDesk), a sessão pode desconectar.%C_RST%
echo.
if "%SILENCIOSO%"=="0" (
    choice /c SN /n /m "   Deseja continuar? [S/N] "
    if errorlevel 2 (
        call :log "Cancelado pelo usuário"
        endlocal & exit /b 0
    )
    echo.
)

:: ------------------------------------------- [1/7] Backup da configuração
echo %C_TIT%[1/7]%C_RST% Salvando backup da configuração atual...
ipconfig /all > "%BKP_IPCONFIG%" 2>&1
netsh -c interface dump > "%BKP_DUMP%" 2>&1
echo       %C_OK%OK%C_RST% %BKP_IPCONFIG%
echo       %C_OK%OK%C_RST% %BKP_DUMP%
call :log "Backups: %BKP_IPCONFIG% / %BKP_DUMP%"

:: Detecta adaptadores conectados com IP fixo (o reset de TCP/IP apaga o IP fixo)
set "QTD_ESTATICO=0"
for /f %%n in ('powershell -NoProfile -Command "@(Get-NetIPInterface -AddressFamily IPv4 -Dhcp Disabled -ConnectionState Connected -ErrorAction SilentlyContinue | Where-Object InterfaceAlias -notlike 'Loopback*').Count"') do set "QTD_ESTATICO=%%n"
if "%QTD_ESTATICO%"=="0" goto :sem_ip_fixo

echo.
echo       %C_AVS%IP FIXO detectado nos adaptadores:%C_RST%
for /f "delims=" %%i in ('powershell -NoProfile -Command "Get-NetIPInterface -AddressFamily IPv4 -Dhcp Disabled -ConnectionState Connected -ErrorAction SilentlyContinue | Where-Object InterfaceAlias -notlike 'Loopback*' | ForEach-Object { $ip = (Get-NetIPAddress -InterfaceIndex $_.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue).IPAddress -join ', '; '         - ' + $_.InterfaceAlias + ' (' + $ip + ')' }"') do echo %%i
call :log "IP fixo detectado em %QTD_ESTATICO% adaptador(es)"
echo       %C_AVS%A redefinição de TCP/IP apaga essas configurações.%C_RST%
echo.
if "%SILENCIOSO%"=="1" (
    if "%FORCAR%"=="1" (
        call :log "Modo /forcar: TCP/IP será redefinido mesmo com IP fixo"
    ) else (
        set "PULAR_IP=1"
        echo       %C_AVS%Modo silencioso: o reset de TCP/IP será PULADO ^(use /forcar^).%C_RST%
        call :log "Reset de TCP/IP pulado (IP fixo, sem /forcar)"
    )
    goto :sem_ip_fixo
)
echo       [S] Redefinir tudo ^(precisarei reconfigurar o IP depois^)
echo       [N] Pular o reset de TCP/IP e fazer o restante
choice /c SN /n /m "      Escolha: "
if errorlevel 2 (
    set "PULAR_IP=1"
    call :log "Usuário optou por pular o reset de TCP/IP"
)
echo.

:sem_ip_fixo

:: ------------------------------------------- [2/7] Libera o DHCP
echo %C_TIT%[2/7]%C_RST% Liberando concessões DHCP...
ipconfig /release >>"%LOG%" 2>&1
ipconfig /release6 >>"%LOG%" 2>&1
echo       %C_OK%OK%C_RST%

:: ------------------------------------------- [3/7] Limpa caches
echo %C_TIT%[3/7]%C_RST% Limpando caches ^(DNS, ARP, NetBIOS^)...
ipconfig /flushdns >>"%LOG%" 2>&1
call :resultado "Cache DNS"
netsh interface ip delete arpcache >>"%LOG%" 2>&1
call :resultado "Cache ARP"
nbtstat -R >>"%LOG%" 2>&1
nbtstat -RR >>"%LOG%" 2>&1
echo       %C_OK%OK%C_RST% Cache NetBIOS

:: ------------------------------------------- [4/7] Reset da pilha de rede
echo %C_TIT%[4/7]%C_RST% Redefinindo a pilha de rede...
if "%PULAR_IP%"=="1" (
    echo       %C_DIM%-- TCP/IP ignorado ^(IP fixo preservado^)%C_RST%
) else (
    netsh int ipv4 reset "%LOGDIR%\reset_ipv4_%STAMP%.log" >>"%LOG%" 2>&1
    call :resultado "TCP/IP v4"
    netsh int ipv6 reset "%LOGDIR%\reset_ipv6_%STAMP%.log" >>"%LOG%" 2>&1
    call :resultado "TCP/IP v6"
)
netsh winsock reset >>"%LOG%" 2>&1
call :resultado "Winsock"

:: ------------------------------------------- [5/7] Reinicia os adaptadores
echo %C_TIT%[5/7]%C_RST% Reiniciando adaptadores físicos ativos...
for /f "delims=" %%a in ('powershell -NoProfile -Command "Get-NetAdapter -Physical -ErrorAction SilentlyContinue | Where-Object Status -ne 'Disabled' | Select-Object -ExpandProperty Name"') do (
    echo       - %%a
    call :log "Reiniciando adaptador: %%a"
)
powershell -NoProfile -Command "Get-NetAdapter -Physical -ErrorAction SilentlyContinue | Where-Object Status -ne 'Disabled' | Restart-NetAdapter -Confirm:$false" >>"%LOG%" 2>&1
call :resultado "Adaptadores reiniciados"
echo       %C_DIM%Aguardando os adaptadores subirem...%C_RST%
call :esperar 8

:: ------------------------------------------- [6/7] Renova o DHCP
echo %C_TIT%[6/7]%C_RST% Renovando IP e registrando no DNS...
ipconfig /renew >>"%LOG%" 2>&1
ipconfig /renew6 >>"%LOG%" 2>&1
ipconfig /registerdns >>"%LOG%" 2>&1
echo       %C_OK%OK%C_RST%

:: ------------------------------------------- [7/7] Teste de conectividade
echo %C_TIT%[7/7]%C_RST% Testando a conectividade...
set "T_GW=FALHA" & set "T_NET=FALHA" & set "T_DNS=FALHA"
set "GATEWAY="
for /f %%g in ('powershell -NoProfile -Command "(Get-NetRoute -DestinationPrefix 0.0.0.0/0 -ErrorAction SilentlyContinue | Sort-Object RouteMetric | Select-Object -First 1).NextHop"') do set "GATEWAY=%%g"

if defined GATEWAY (
    ping -n 2 -w 1500 %GATEWAY% | find "TTL=" >nul && set "T_GW=OK"
) else (
    set "GATEWAY=não encontrado"
)
ping -n 2 -w 1500 1.1.1.1 | find "TTL=" >nul && set "T_NET=OK"
ping -n 2 -w 1500 8.8.8.8 | find "TTL=" >nul && set "T_NET=OK"
powershell -NoProfile -Command "if (Resolve-DnsName microsoft.com -QuickTimeout -ErrorAction SilentlyContinue) { exit 0 } else { exit 1 }" && set "T_DNS=OK"

call :mostrar_teste "Gateway (%GATEWAY%)" %T_GW%
call :mostrar_teste "Internet (1.1.1.1 / 8.8.8.8)" %T_NET%
call :mostrar_teste "Resolução DNS" %T_DNS%
call :log "Testes: gateway=%T_GW% internet=%T_NET% dns=%T_DNS%"

if not "%T_NET%%T_DNS%"=="OKOK" set "RC=3"
if not "%FALHAS%"=="0" set "RC=2"

:: ============================================================================
echo.
echo %C_TIT%  ──────────────────────────── RESUMO ────────────────────────────%C_RST%
if "%RC%"=="0" echo    Resultado : %C_OK%SUCESSO - rede redefinida e funcionando%C_RST%
if "%RC%"=="2" echo    Resultado : %C_AVS%CONCLUÍDO COM %FALHAS% FALHA^(S^) - veja o log%C_RST%
if "%RC%"=="3" echo    Resultado : %C_AVS%CONCLUÍDO - conectividade ainda não confirmada%C_RST%
if "%PULAR_IP%"=="0" if not "%QTD_ESTATICO%"=="0" (
    echo    %C_AVS%IP fixo foi apagado. Para restaurar:%C_RST%
    echo    %C_DIM%netsh -f "%BKP_DUMP%"%C_RST%
)
echo    Backup    : %BKP_IPCONFIG%
echo    Log       : %LOG%
echo    %C_AVS%Reinicie o computador para concluir o reset do Winsock/TCP-IP.%C_RST%
echo %C_TIT%  ────────────────────────────────────────────────────────────────%C_RST%
call :log "FIM - código de saída %RC%"
echo.

if "%REINICIAR%"=="1" goto :reiniciar
if "%SILENCIOSO%"=="1" goto :sair
choice /c SN /n /m "   Reiniciar o computador agora? [S/N] "
if errorlevel 2 goto :sair

:reiniciar
call :log "Reinicialização agendada"
shutdown /r /t 15 /c "Reiniciando para concluir o reset de rede. Para cancelar: shutdown /a"
echo    %C_AVS%Reiniciando em 15 segundos... ^(para cancelar: shutdown /a^)%C_RST%
if "%SILENCIOSO%"=="0" call :esperar 3

:sair
endlocal & exit /b %RC%

:: ============================================================================
::  Sub-rotinas
:: ============================================================================
:resultado
if errorlevel 1 (
    echo       %C_AVS%AVISO%C_RST% %~1 retornou erro ^(detalhes no log^)
    call :log "AVISO: %~1 retornou erro"
    set /a FALHAS+=1
) else (
    echo       %C_OK%OK%C_RST% %~1
)
exit /b

:mostrar_teste
if "%~2"=="OK" (
    echo       %C_OK%OK   %C_RST% %~1
) else (
    echo       %C_ERR%FALHA%C_RST% %~1
)
exit /b

:esperar
set /a "_n=%~1+1"
ping -n %_n% 127.0.0.1 >nul
exit /b

:log
>>"%LOG%" echo [%date% %time:~0,8%] %~1
exit /b
