"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamHandler = void 0;
const Object_1 = require("./Object");
const String_1 = require("./String");
/**
 * Handles stdout/stderr stream processing for child processes.
 * Manages stream event listeners, data routing, and error handling.
 */
class StreamHandler {
    emitter;
    #logger;
    constructor(options, emitter) {
        this.emitter = emitter;
        this.#logger = options.logger;
    }
    /**
     * Set up stream event listeners for a child process
     */
    setupStreamListeners(proc, context) {
        const stdin = proc.stdin;
        if (stdin == null)
            throw new Error("Given proc had no stdin");
        stdin.on("error", (err) => context.onError("stdin.error", err));
        const stdout = proc.stdout;
        if (stdout == null)
            throw new Error("Given proc had no stdout");
        stdout.on("error", (err) => context.onError("stdout.error", err));
        stdout.on("data", (data) => this.#onStdout(data, context));
        (0, Object_1.map)(proc.stderr, (stderr) => {
            stderr.on("error", (err) => context.onError("stderr.error", err));
            stderr.on("data", (data) => this.#onStderr(data, context));
        });
    }
    /**
     * Handle stdout data from a child process
     */
    #onStdout(data, context) {
        if (data == null)
            return;
        const task = context.getCurrentTask();
        if (task != null && task.pending) {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
            this.emitter.emit("taskData", data, task, context);
            task.onStdout(data);
        }
        else if (context.isEnding()) {
            // don't care if we're already being shut down.
        }
        else if (!(0, String_1.blank)(data)) {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
            this.emitter.emit("noTaskData", data, null, context);
            context.end(false, "stdout.error");
        }
    }
    /**
     * Handle stderr data from a child process
     */
    #onStderr(data, context) {
        if ((0, String_1.blank)(data))
            return;
        this.#logger().warn(context.name + ".onStderr(): " + String(data));
        const task = context.getCurrentTask();
        if (task != null && task.pending) {
            task.onStderr(data);
        }
        else if (!context.isEnding()) {
            // If we're ending and there isn't a task, don't worry about it.
            // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
            this.emitter.emit("noTaskData", null, data, context);
            context.end(false, "stderr");
        }
    }
    /**
     * Process stdout data directly (for testing or manual processing)
     */
    processStdout(data, context) {
        this.#onStdout(data, context);
    }
    /**
     * Process stderr data directly (for testing or manual processing)
     */
    processStderr(data, context) {
        this.#onStderr(data, context);
    }
    /**
     * Check if data is considered blank/empty
     */
    isBlankData(data) {
        return (0, String_1.blank)(data);
    }
    /**
     * Get stream handler statistics
     */
    getStats() {
        return {
            handlerActive: true,
            emitterConnected: this.emitter != null,
        };
    }
}
exports.StreamHandler = StreamHandler;
//# sourceMappingURL=StreamHandler.js.map