import fs from "node:fs";
import http from "node:http";
import path from "node:path";
import { getConfigDir } from "../config/index.js";
const TUI_PORT_FILE = "tui-port";
export function readTuiPort() {
    try {
        const portFile = path.join(getConfigDir(), TUI_PORT_FILE);
        const content = fs.readFileSync(portFile, "utf-8").trim();
        const port = parseInt(content, 10);
        return Number.isFinite(port) && port > 0 ? port : null;
    }
    catch {
        return null;
    }
}
function httpGet(url) {
    return new Promise((resolve, reject) => {
        const req = http.get(url, (res) => {
            let data = "";
            res.on("data", (chunk) => { data += chunk.toString(); });
            res.on("end", () => {
                if (res.statusCode && res.statusCode >= 400) {
                    reject(new Error(`HTTP ${res.statusCode}: ${data}`));
                }
                else {
                    resolve(data);
                }
            });
        });
        req.on("error", reject);
        req.setTimeout(5000, () => { req.destroy(new Error("Timeout")); });
    });
}
function httpPost(url, body, timeoutMs = 5000) {
    return new Promise((resolve, reject) => {
        const data = JSON.stringify(body);
        const parsed = new URL(url);
        const req = http.request({
            hostname: parsed.hostname,
            port: parsed.port,
            path: parsed.pathname,
            method: "POST",
            headers: { "content-type": "application/json", "content-length": Buffer.byteLength(data) },
        }, (res) => {
            let result = "";
            res.on("data", (chunk) => { result += chunk.toString(); });
            res.on("end", () => {
                if (res.statusCode && res.statusCode >= 400) {
                    reject(new Error(`HTTP ${res.statusCode}: ${result}`));
                }
                else {
                    resolve(result);
                }
            });
        });
        req.on("error", reject);
        req.setTimeout(timeoutMs, () => { req.destroy(new Error("Timeout")); });
        req.write(data);
        req.end();
    });
}
export class TuiClient {
    baseUrl;
    sender;
    constructor(port, host = "127.0.0.1") {
        this.baseUrl = `http://${host}:${port}`;
        this.sender = `tui-${process.pid}`;
    }
    async getStatus() {
        const data = await httpGet(`${this.baseUrl}/tui/status`);
        return JSON.parse(data);
    }
    async getLogs(count = 50) {
        const data = await httpGet(`${this.baseUrl}/tui/logs`);
        const entries = JSON.parse(data);
        return entries.slice(-count);
    }
    async sendMessage(text) {
        const data = await httpPost(`${this.baseUrl}/tui/send`, { text, sender: this.sender });
        return JSON.parse(data);
    }
    async restart() {
        const data = await httpPost(`${this.baseUrl}/tui/restart`, {});
        return JSON.parse(data);
    }
    async upgrade(tag = "latest") {
        const data = await httpPost(`${this.baseUrl}/tui/upgrade`, { tag }, 60_000);
        return JSON.parse(data);
    }
    async rdp(ttlMinutes = 30) {
        const data = await httpPost(`${this.baseUrl}/tui/rdp`, { ttlMinutes });
        return JSON.parse(data);
    }
    async switchSession(target) {
        const data = await httpPost(`${this.baseUrl}/tui/switch`, { target });
        return JSON.parse(data);
    }
    async wake() {
        const data = await httpPost(`${this.baseUrl}/tui/wake`, {});
        return JSON.parse(data);
    }
    connectEvents(onEvent, onError) {
        let destroyed = false;
        let req = null;
        const connect = () => {
            if (destroyed)
                return;
            req = http.get(`${this.baseUrl}/tui/events?sender=${encodeURIComponent(this.sender)}`, (res) => {
                let partial = "";
                res.on("data", (chunk) => {
                    partial += chunk.toString();
                    const lines = partial.split("\n");
                    partial = lines.pop() ?? "";
                    for (const line of lines) {
                        if (line.startsWith("data: ")) {
                            try {
                                const event = JSON.parse(line.slice(6));
                                onEvent(event);
                            }
                            catch { /* ignore parse errors */ }
                        }
                    }
                });
                res.on("end", () => {
                    if (!destroyed)
                        setTimeout(connect, 2000);
                });
                res.on("error", (err) => {
                    if (!destroyed) {
                        onError(err);
                        setTimeout(connect, 3000);
                    }
                });
            });
            req.on("error", (err) => {
                if (!destroyed) {
                    onError(err);
                    setTimeout(connect, 3000);
                }
            });
        };
        connect();
        return {
            close: () => {
                destroyed = true;
                req?.destroy();
            },
        };
    }
}
//# sourceMappingURL=client.js.map