@echo off
setlocal enabledelayedexpansion
cls

REM ============================================================
REM  3_Atualizacao_Albert.bat  v4.0  (esptool + plaintext HTTPS)
REM ============================================================
REM
REM  Atualiza firmware do Albert via USB usando esptool stub +
REM  plaintext servido via HTTPS pelo AlbertService. Plaintext fica
REM  apenas em RAM Python (chunks zerados conforme enviados),
REM  nunca toca o disco do laptop. K3 hardware (eFuse BLK1) cifra
REM  ao gravar.
REM
REM  Fluxo (tudo orquestrado pelo Python — bat so faz prompts):
REM    1. Detecta porta COM.
REM    2. Le numSerie via whoami serial (115200 baud, modo app).
REM    3. Operador entra versao alvo (ex: v1.8.18.bin). Bat
REM       registra target via POST /ota_target/device/<NS>.
REM    4. Invoca tools/usb_esptool_push.py que faz:
REM       - whoami (descobre running=app0/app1 → offset 0x10000/0x1F0000)
REM       - GET /usb_update_bundle/<NS> → target + plaintext_url + meta_url
REM       - GET <meta_url> → sha256_plain + size_plain
REM       - GET <plaintext_url> streaming → bytearray em RAM
REM       - esptool.detect_chip → run_stub → attach_flash
REM       - flash_begin(size, offset, encrypted_write=True)
REM       - loop flash_block(chunk, seq, encrypted=True) + zera chunk
REM       - flash_finish + hard_reset
REM    5. Desregistra target no servidor (POST com versao="") — fecha
REM       ciclo CMD12. Sem isso, servidor continua ofertando CMD12 ate
REM       o Albert mandar CMD1 novo, e device poderia baixar a mesma
REM       versao via OTA HTTPS (inocuo, so desperdicio de banda).
REM    6. Monitor serial pra validar SW_V novo.
REM
REM  Pre-condicoes:
REM    - Albert ja instalado em campo via 2_Primeira_Instalacao
REM    - Firmware >= v1.8.17 no device (introduziu running= no whoami)
REM    - Python + pyserial + esptool + cryptography no PATH
REM    - Endpoint /service/api/plaintext_firmware/ no AlbertService
REM    - Nenhuma outra janela usando a COM (Arduino IDE / miniterm fechados)
REM ============================================================

set "IOT_HOST=http://iot.mgconnect.online"
set "TITLE=Albert Flash V4 - Atualizacao via esptool"
set "SERIAL_TOOL=%~dp0tools\albert_serial.py"
set "PUSH_TOOL=%~dp0tools\usb_esptool_push.py"
set "BIN_DIR=%~dp0bin"

echo ============================================================
echo  %TITLE%
echo ============================================================
echo.

REM Pre-flight checks
where python >nul 2>&1
if errorlevel 1 (
    echo [ERRO] Python nao encontrado no PATH.
    pause
    exit /b 1
)
where curl >nul 2>&1
if errorlevel 1 (
    echo [ERRO] curl nao encontrado no PATH.
    pause
    exit /b 1
)
if not exist "%SERIAL_TOOL%" (
    echo [ERRO] tools\albert_serial.py nao encontrado.
    pause
    exit /b 1
)
if not exist "%PUSH_TOOL%" (
    echo [ERRO] tools\usb_esptool_push.py nao encontrado.
    pause
    exit /b 1
)
if not exist "%BIN_DIR%" mkdir "%BIN_DIR%" 2>nul

REM ============================================================
REM ETAPA 1: Porta COM + whoami
REM ============================================================
echo [1/6] Detectando porta COM do Albert...
for /f %%P in ('python "%SERIAL_TOOL%" detect-port 2^>nul') do set "COM_PORT=%%P"
if not defined COM_PORT (
    echo [ERRO] Nenhuma porta serial valida detectada.
    pause
    exit /b 1
)
echo  Porta detectada: !COM_PORT!
echo.

echo [2/6] Lendo identidade do device via whoami...
set "NS_ATUAL="
set "SW_ATUAL="
set "RUN_ATUAL="
for /f "tokens=1,2 delims==" %%K in ('python "%SERIAL_TOOL%" whoami !COM_PORT! 2^>nul') do (
    if "%%K"=="numSerie" set "NS_ATUAL=%%L"
    if "%%K"=="sw"       set "SW_ATUAL=%%L"
    if "%%K"=="running"  set "RUN_ATUAL=%%L"
)
if not defined NS_ATUAL (
    echo [ERRO] whoami nao respondeu. Firmware ^>= v1.8.17? Sicherung 1?
    pause
    exit /b 1
)
if not defined RUN_ATUAL (
    echo [ERRO] whoami nao retornou campo 'running'. Firmware precisa ser ^>= v1.8.17 com whoami atualizado.
    pause
    exit /b 1
)
echo  Device: !NS_ATUAL!  SW: !SW_ATUAL!  Particao: !RUN_ATUAL!
echo.

REM ============================================================
REM ETAPA 3: Versao alvo + registra target no admin
REM ============================================================
echo [3/6] Registrando target version no AlbertService...
echo.
echo  Exemplos de versao: v2.0.0.bin
echo  ^(Tem que existir em /home/mgtech/albert_service/firmware/^<modelo^>/ no servidor.^)
echo.
set TARGET_INPUT=
set /p TARGET_INPUT=  Versao alvo pro !NS_ATUAL!:
if not defined TARGET_INPUT (
    echo [ERRO] Versao vazia. Abortando.
    pause
    exit /b 1
)

echo  POST /ota_target/device/!NS_ATUAL!  payload={"versao":"!TARGET_INPUT!"}
curl -fsS -X POST -H "Content-Type: application/json" ^
    -d "{\"versao\":\"!TARGET_INPUT!\"}" ^
    "!IOT_HOST!/service/api/ota_target/device/!NS_ATUAL!" ^
    -o "!BIN_DIR!\ota_target_resp.json" 2>nul
if errorlevel 1 (
    echo [ERRO] Falha ao registrar target. Verifique:
    echo  - Conexao com !IOT_HOST!
    echo  - A versao !TARGET_INPUT! existe no servidor
    pause
    exit /b 1
)
echo  Target registrado.
echo.

REM ============================================================
REM ETAPA 4: Confirmacao operador
REM ============================================================
echo [4/6] Confirmacao da atualizacao
echo ============================================================
echo  Device      : !NS_ATUAL!
echo  Porta       : !COM_PORT!
echo  Versao atual: !SW_ATUAL!  ^(rodando em !RUN_ATUAL!^)
echo  Target      : !TARGET_INPUT!
echo  Servidor    : !IOT_HOST!
echo.
echo  esptool grava na particao !RUN_ATUAL! (sobrescreve a ativa).
echo  Apos isso, hard_reset e Albert volta na MESMA particao com o
echo  firmware novo. NVS ^(sigla, placa, hab, DL, EDGEV1^) preservada.
echo  Plaintext do firmware NUNCA toca o disco do laptop.
echo ============================================================
echo.
set CONFIRMA=
set /p CONFIRMA=  Confirma atualizar para !TARGET_INPUT!? [SIM/nao]:
if /i not "!CONFIRMA!"=="SIM" (
    echo Cancelado pelo operador.
    pause
    exit /b 0
)
echo.

REM ============================================================
REM ETAPA 5: Empurra firmware via esptool stub
REM ============================================================
echo [5/6] Empurrando firmware via esptool (plaintext em RAM, K3 cifra na flash)...
echo.
python "%PUSH_TOOL%" --port !COM_PORT! --numserie !NS_ATUAL! --base-url "!IOT_HOST!"
set "PUSH_RC=!errorlevel!"
echo.
if not "!PUSH_RC!"=="0" (
    echo [ERRO] usb_esptool_push falhou ^(rc=!PUSH_RC!^).
    echo Veja saida acima pra detalhes.
    pause
    exit /b 1
)

REM ============================================================
REM ETAPA 6: Desregistra target no servidor (fecha ciclo CMD12)
REM ============================================================
REM Sem isso, servidor continua oferecendo CMD12 ate o Albert mandar
REM CMD1 novo com SW_V atualizado. Device poderia receber CMD12 nesse
REM intervalo e baixar v.X.X de novo via OTA HTTPS — gravando em app0
REM (oposta da ativa). Inocuo mas desperdicio. POST com versao=""
REM zera o registry pra esse device.
echo [6/6] Desregistrando target no servidor (fecha ciclo CMD12)...
curl -fsS -X POST -H "Content-Type: application/json" ^
    -d "{\"versao\":\"\"}" ^
    "!IOT_HOST!/service/api/ota_target/device/!NS_ATUAL!" ^
    -o "!BIN_DIR!\ota_target_resp.json" 2>nul
if errorlevel 1 (
    echo  [AVISO] Falha ao desregistrar target. Albert pode receber CMD12 redundante apos boot.
    echo  ^(Nao bloqueia: device baixa a mesma versao via OTA HTTPS, sem dano.^)
) else (
    echo  Target desregistrado. CMD12 ciclo fechado.
)
echo.

echo ============================================================
echo  Flash concluido. Albert reiniciou.
echo  Aguardando boot ^(~10s^) antes de abrir monitor...
echo ============================================================
timeout /t 10 /nobreak >nul

REM ============================================================
REM Monitor serial pra validacao
REM ============================================================
echo Abrindo monitor pra inspecao do boot novo.
echo Esperado:
echo   SW_V: !TARGET_INPUT:.bin=!  (sem o .bin)
echo   Sicherung 1
echo   EDGEV1 aplicado em edgeActive.
echo Para sair: CTRL + ]
echo ============================================================
echo.

python -m serial.tools.miniterm !COM_PORT! 115200

echo.
echo ============================================================
echo  Atualizacao concluida.
echo ============================================================
pause
