"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RpcStdinProcessor = void 0;
const readline_1 = __importDefault(require("readline"));
class RpcStdinProcessor {
    constructor(child) {
        this.child = child;
        this.handlers = {};
        this.isClosed = false;
    }
    handler(method, handler) {
        this.handlers[method] = handler;
    }
    onMessage(callback) {
        this.messageCallback = callback;
    }
    async handle(method, input) {
        const handler = this.handlers[method];
        if (!handler) {
            throw new Error(`Handler for method ${method} not found`);
        }
        return handler(input);
    }
    response(id, result, error) {
        if (id && !this.isClosed && this.child.stdin && !this.child.killed) {
            const responseMessage = {
                type: 'rpc_response',
                id,
                result: error ? undefined : result,
                error: error ? String(error) : undefined
            };
            const messageStr = JSON.stringify(responseMessage);
            this.child.stdin.write(messageStr + '\n');
        }
    }
    async init() {
        if (this.child.stdout) {
            this.rl = readline_1.default.createInterface({
                input: this.child.stdout,
                crlfDelay: Infinity
            });
            this.rl.on('line', (line) => {
                try {
                    const msg = JSON.parse(line.trim());
                    // Call generic message callback if registered
                    if (this.messageCallback) {
                        this.messageCallback(msg);
                    }
                    // Handle RPC requests specifically
                    if (msg && msg.type === 'rpc_request') {
                        const { id, method, args } = msg;
                        this.handle(method, args)
                            .then((result) => this.response(id, result, null))
                            .catch((error) => this.response(id, null, error));
                    }
                }
                catch (error) {
                    console.error('Failed to parse RPC message:', error, 'Raw line:', line);
                }
            });
            this.rl.on('close', () => {
                this.isClosed = true;
            });
        }
        this.child.on('exit', () => {
            this.isClosed = true;
        });
        this.child.on('close', () => {
            this.isClosed = true;
        });
    }
    close() {
        this.isClosed = true;
        this.messageCallback = undefined;
        if (this.rl) {
            this.rl.close();
        }
    }
}
exports.RpcStdinProcessor = RpcStdinProcessor;
