@echo off
chcp 65001 > nul
setlocal enabledelayedexpansion

if "%~1" == "" goto missingArgs
if "%~2" == "" goto missingArgs
if "%~3" == "" goto missingArgs

set "pluginProcessId=%~1"
set "geckoDriverProcessId=%~2"
set "outputFile=%~3"
set /A process_count=0

REM Print header
echo ********************************************************************************************* >> "%outputFile%"
echo                               LOG START - %date% %time% >> "%outputFile%"
echo ********************************************************************************************* >> "%outputFile%"

echo Watchdog initialized. Monitoring plugin process with PID: %pluginProcessId% and GeckoDriver process with PID: %geckoDriverProcessId%. >> "%outputFile%"

REM Retrieve initial process information using wmic to build process tree
set "pluginProcessName="
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic process where "ProcessId=%pluginProcessId%" get ParentProcessId^,Name /value 2^>NUL`) do (
    if not "%%~i" == "" (
        set "field=%%~i"
        set "value=%%~j"
        
        if "!field!"=="ParentProcessId" (
            set "frontProcessId=!value!"
        )
        if "!field!"=="Name" (
            set "pluginProcessName=!value!"
        )
    )
)

if defined pluginProcessName (
    echo Added process to watchdog monitor: %pluginProcessName%, PID=%pluginProcessId% >> "%outputFile%"
    set /A process_count+=1
) else (
    echo Plugin process with PID %pluginProcessId% is NOT running.
    goto endTree
)

REM Check if frontProcessId was set; if not, stop building the tree
if not defined frontProcessId (
    echo No parent process found for PID %pluginProcessId%. Stopping tree build. >> "%outputFile%"
    goto endTree
)

REM Retrieve and log the front process information using wmic
for /F "tokens=1,2 delims==" %%i in ('wmic process where "ProcessId=%frontProcessId%" get Name /value 2^>NUL') do (
    if "%%~i"=="Name" (
        set "frontProcessName=%%j"
    )
)

if defined frontProcessName (
    echo Added process to watchdog monitor: %frontProcessName%, PID=%frontProcessId% >> "%outputFile%"
    set /A process_count+=1
) else (
    echo Front process with PID %frontProcessId% is NOT running.
    goto endTree
)

:endTree

echo Monitoring loop started. >> "%outputFile%"
:monitorLoop
REM Count the number of living processes by checking each individually with tasklist
set "matched_count=0"

:: Check pluginProcessId
tasklist /FI "PID eq %pluginProcessId%" | findstr /I /C:"%pluginProcessId%" >NUL
if %ERRORLEVEL% equ 0 set /A matched_count+=1

:: Check frontProcessId if it exists
if defined frontProcessId (
    tasklist /FI "PID eq %frontProcessId%" | findstr /I /C:"%frontProcessId%" >NUL
    if %ERRORLEVEL% equ 0 set /A matched_count+=1
)

REM Verify if all expected processes are running
if %matched_count% NEQ %process_count% (
    echo One or more processes in the tree are missing. >> "%outputFile%"
    goto terminateGeckoDriver
)

REM Wait 4 seconds before checking again
timeout /t 4 > nul
goto monitorLoop

:terminateGeckoDriver
echo Terminating geckodriver process (PID: %geckoDriverProcessId%) and its child processes. >> "%outputFile%"
taskkill /F /PID %geckoDriverProcessId% /T >> "%outputFile%" 2>&1
if errorlevel 1 goto terminateFailed

echo GeckoDriver process (PID: %geckoDriverProcessId%) and its child processes have been terminated successfully. >> "%outputFile%"
echo Exiting watchdog process. >> "%outputFile%"
exit /b 0

:missingArgs
echo Missing required arguments. >> "%outputFile%" 2>&1
echo Usage: %~nx0 ^<pluginProcessId^> ^<geckoDriverProcessId^> ^<outputFile^> >> "%outputFile%" 2>&1
echo Exiting with error code 1 due to missing arguments. >> "%outputFile%" 2>&1
exit /b 1

:terminateFailed
echo Failed to terminate the geckodriver process (PID: %geckoDriverProcessId%) and its child processes. >> "%outputFile%" 2>&1
echo Exiting with error code 1 due to failure in terminating GeckoDriver. >> "%outputFile%" 2>&1
exit /b 1
