"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.streamWS = exports.callWS = void 0;
const ws_1 = require("ws");
const commander_1 = require("commander");
const uuid_1 = require("uuid");
const fs_1 = require("fs");
const child_process_1 = require("child_process");
const updatercli_1 = require("./pl2/updater/updatercli");
const constants_1 = require("../src/constants");
function isRoot() {
    if (process.getuid)
        return process.getuid() == 0;
    return false;
}
const isPL2 = async () => {
    try {
        await fs_1.promises.access("/opt/build-info/prolinux-info.txt");
        return true;
    }
    catch (e) {
        return false;
    }
};
async function spawnChild(command) {
    const child = (0, child_process_1.spawn)('/bin/sh', ["-c", command]);
    let data = "";
    for await (const chunk of child.stdout) {
        console.log('stdout chunk: ' + chunk);
        data += chunk;
    }
    for await (const chunk of child.stderr) {
        console.error('stderr chunk: ' + chunk);
        data += chunk;
    }
    const exitCode = await new Promise((resolve, reject) => {
        child.on('close', resolve);
    });
    return { data, exitCode };
}
function connectWS() {
    let ws = new ws_1.WebSocket("ws+unix:///tmp/prolinuxd.sock");
    return new Promise((resolve, reject) => {
        ws.on("open", () => {
            resolve(ws);
        });
        ws.on("error", (err) => {
            reject(err);
        });
    });
}
function callWS(action, payload, promise = true) {
    return new Promise(async (resolve, reject) => {
        const ws = await connectWS();
        let id = (0, uuid_1.v4)();
        let msg = { action, payload, id };
        console.log("[Call] Sending message: " + JSON.stringify(msg));
        if (promise) {
            const listener = (e) => {
                //console.log("[Call] Received message: " + e.data);
                let msg = JSON.parse(e.data);
                if (msg.id === id) {
                    if (msg.payload.status) {
                        resolve(msg.payload.data);
                    }
                    else {
                        reject(new Error(msg.payload.data.msg));
                    }
                    ws.removeEventListener("message", listener);
                    ws.close();
                }
            };
            ws.addEventListener("message", listener);
        }
        ws.send(JSON.stringify(msg));
        setTimeout(() => {
            if (promise) {
                ws.close();
                reject(new Error("Timed out waiting for response from ProLinuxD"));
            }
        }, 5000);
        if (!promise) {
            ws.close();
            resolve({});
        }
        ;
    });
}
exports.callWS = callWS;
// streams data with the specified action
async function streamWS(action, callback) {
    const ws = await connectWS();
    ws.on("message", (e) => {
        let msg = JSON.parse(e.toString());
        if (msg.action === action) {
            callback(msg.payload, ws);
        }
    });
    return () => {
        ws.close();
    };
}
exports.streamWS = streamWS;
const program = new commander_1.Command();
async function main() {
    program
        .name('plctl')
        .description('ProLinuxD CLI Utility')
        .version('0.0.1');
    /* ----------- */
    program.command('status')
        .description('get the status of ProLinuxD')
        .action(async (str, options) => {
        let res = await callWS(constants_1.LocalActions.STATUS, {});
        console.log("-------------------------------------------------");
        console.log("Status: " + res.status);
        console.log("Cloud Connected: " + res.ocsConnnected);
        console.log("Cloud Ready (Authenticated): " + res.ocsReady);
        if ((await isPL2()))
            console.log("Selected Root: " + res.selectedRoot);
        if ((await isPL2()))
            console.log("Locked Root: " + res.lockedRoot);
        if ((await isPL2()))
            console.log("Hostname: " + res.hostname);
        if ((await isPL2()))
            console.log("KExec Disabled: " + res.disableKexec);
        if ((await isPL2()))
            console.log("Build Info: " + res.buildInfo.product + " " + res.buildInfo.variant + " " + res.buildInfo.channel + " " + res.buildInfo.arch + " - " + res.buildInfo.buildnum + "," + res.buildInfo.uuid + " (" + res.buildInfo.builddate + ")");
        process.exit(0);
    });
    /* ----------- */
    program.command('set-device-token')
        .description('set the Sineware Cloud device token')
        .argument('<token>', 'device token')
        .action((str, options) => {
        callWS(constants_1.LocalActions.SET_TOKEN, { token: str }, false);
        console.log("Device token set to " + str);
    });
    /* ----------- */
    program.command('logs')
        .description('view logs collected by prolinuxd on this device')
        .action(async (str, options) => {
        let res = await callWS(constants_1.LocalActions.GET_LOGS, {});
        console.log("-------------------------------------------------");
        console.log(res.logs.join("\n"));
        process.exit(0);
    });
    if (await isPL2()) {
        await (0, updatercli_1.registerPL2Commands)(program);
    }
    process.on('uncaughtException', (err) => {
        console.error(err);
        process.exit(1);
    });
    program.parse();
}
main();
//# sourceMappingURL=plctl.js.map