/**
 * @license
 * Copyright 2026 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import process from 'node:process';
import readline from 'node:readline';
import { parseArgs } from 'node:util';
import { logger, flushLogs, saveLogsToFile } from '../../logger.js';
import { WatchdogMessageType } from '../types.js';
import { ClearcutSender } from './ClearcutSender.js';
function parseWatchdogArgs() {
    const { values } = parseArgs({
        options: {
            'parent-pid': { type: 'string' },
            'app-version': { type: 'string' },
            'os-type': { type: 'string' },
            'log-file': { type: 'string' },
            'clearcut-endpoint': { type: 'string' },
            'clearcut-force-flush-interval-ms': { type: 'string' },
            'clearcut-include-pid-header': { type: 'boolean' },
        },
        strict: true,
    });
    // Verify required arguments
    const parentPid = parseInt(values['parent-pid'] ?? '', 10);
    const appVersion = values['app-version'];
    const osType = parseInt(values['os-type'] ?? '', 10);
    if (isNaN(parentPid) || !appVersion || isNaN(osType)) {
        console.error('Invalid arguments provided for watchdog process: ', JSON.stringify({ parentPid, appVersion, osType }));
        process.exit(1);
    }
    // Parse Optional Arguments
    const logFile = values['log-file'];
    const clearcutEndpoint = values['clearcut-endpoint'];
    const clearcutIncludePidHeader = values['clearcut-include-pid-header'];
    let clearcutForceFlushIntervalMs;
    if (values['clearcut-force-flush-interval-ms']) {
        const parsed = parseInt(values['clearcut-force-flush-interval-ms'], 10);
        if (!isNaN(parsed)) {
            clearcutForceFlushIntervalMs = parsed;
        }
    }
    return {
        parentPid,
        appVersion,
        osType,
        logFile,
        clearcutEndpoint,
        clearcutForceFlushIntervalMs,
        clearcutIncludePidHeader,
    };
}
function main() {
    const { parentPid, appVersion, osType, logFile, clearcutEndpoint, clearcutForceFlushIntervalMs, clearcutIncludePidHeader, } = parseWatchdogArgs();
    let logStream;
    if (logFile) {
        logStream = saveLogsToFile(logFile);
    }
    const exit = (code) => {
        if (!logStream) {
            process.exit(code);
        }
        void flushLogs(logStream).finally(() => {
            process.exit(code);
        });
    };
    logger('Watchdog started', JSON.stringify({
        pid: process.pid,
        parentPid,
        version: appVersion,
        osType,
    }, null, 2));
    const sender = new ClearcutSender({
        appVersion,
        osType: osType,
        clearcutEndpoint,
        forceFlushIntervalMs: clearcutForceFlushIntervalMs,
        includePidHeader: clearcutIncludePidHeader,
    });
    let isShuttingDown = false;
    function onParentDeath(reason) {
        if (isShuttingDown) {
            return;
        }
        isShuttingDown = true;
        logger(`Parent death detected (${reason}). Sending shutdown event...`);
        sender
            .sendShutdownEvent()
            .then(() => {
            logger('Shutdown event sent. Exiting.');
            exit(0);
        })
            .catch(err => {
            logger('Failed to send shutdown event', err);
            exit(1);
        });
    }
    process.stdin.on('end', () => onParentDeath('stdin end'));
    process.stdin.on('close', () => onParentDeath('stdin close'));
    process.on('disconnect', () => onParentDeath('ipc disconnect'));
    const rl = readline.createInterface({
        input: process.stdin,
        terminal: false,
    });
    rl.on('line', line => {
        try {
            if (!line.trim()) {
                return;
            }
            const msg = JSON.parse(line);
            if (msg.type === WatchdogMessageType.LOG_EVENT && msg.payload) {
                sender.enqueueEvent(msg.payload);
            }
        }
        catch (err) {
            logger('Failed to parse IPC message', err);
        }
    });
}
try {
    main();
}
catch (err) {
    console.error('Watchdog fatal error:', err);
    process.exit(1);
}
