"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TcpUdpPortsTerminalUI = void 0;
//#region imports
const lib_1 = require("tnp-core/lib");
const index_1 = require("../../index");
const base_cli_worker_terminal_ui_1 = require("../classes/base-cli-worker/base-cli-worker-terminal-ui");
//#endregion
class TcpUdpPortsTerminalUI extends base_cli_worker_terminal_ui_1.BaseCliWorkerTerminalUI {
    //#region methods / header text
    async headerText() {
        return 'TCP/UDP|Ports DB';
    }
    //#endregion
    //#region methods / header text style
    textHeaderStyle() {
        return 'block';
    }
    //#endregion
    //#region methods / crud menu for take by os ports
    async crudMenuForTakeByOsPorts() {
        const { selected: actionChoice } = await lib_1.UtilsTerminal.selectActionAndExecute({
            back: {
                name: ' - back - ',
            },
            editPort: {
                name: 'Edit port',
            },
            addPort: {
                name: 'Add port',
            },
            deletePort: {
                name: 'Delete port (make it unassigned)',
            },
        });
        switch (actionChoice) {
            case 'editPort':
                await this.editPortTerminalUiProcess();
                break;
            case 'addPort':
                await this.addPortTerminalUiProcess();
                break;
            case 'deletePort':
                await this.deletePortTerminalUiProcess();
                break;
        }
    }
    //#endregion
    //#region methods / add port process
    async addPortTerminalUiProcess() {
        //#region @backendFunc
        const ctrl = await this.worker.getRemoteControllerFor({
            methodOptions: {
                calledFrom: 'addPortTerminalUiProcess',
            },
        });
        let portToAdd = await this.getNewPortToAdd();
        while (true) {
            const uniqueId = await lib_1.UtilsTerminal.input({
                defaultValue: `my-service-on-port-${portToAdd}`,
                question: 'Enter service unique description',
            });
            try {
                await lib_1.UtilsTerminal.pressAnyKeyToContinueAsync();
                const addedPort = (await ctrl
                    .addTakeByOsPort(portToAdd, encodeURIComponent(uniqueId))
                    .request()).body.json;
                await lib_1.UtilsTerminal.pressAnyKeyToContinueAsync({
                    message: `Port ${addedPort.port} added successfully. Press any key to continue...`,
                });
                return;
            }
            catch (error) {
                await lib_1.UtilsTerminal.pressAnyKeyToContinueAsync({
                    message: 'Something went wrong. Press any key to continue...',
                });
                return;
            }
        }
        //#endregion
    }
    //#endregion
    //#region methods / select port process
    async selectPortProcess(ports, title) {
        //#region @backendFunc
        const selectedPort = await lib_1.UtilsTerminal.select({
            question: title,
            choices: [
                {
                    name: 'Back',
                    value: undefined,
                },
                ...ports.map(p => ({
                    name: p.titleOnList,
                    value: p.port,
                })),
            ],
        });
        return ports.find(f => f.port === selectedPort);
        //#endregion
    }
    //#endregion
    //#region methods / delete port process
    async deletePortTerminalUiProcess() {
        //#region @backendFunc
        const ctrl = await this.worker.getRemoteControllerFor({
            methodOptions: {
                calledFrom: 'deletePortTerminalUiProcess',
            },
        });
        const portsTakeByOs = (await ctrl.getPortsByStatus('assigned-taken-by-os').request()).body.json;
        const selectedPort = await this.selectPortProcess(portsTakeByOs, 'Select port to delete (make it unassigned)');
        if (!selectedPort) {
            return;
        }
        try {
            await ctrl.deletePort(selectedPort.port).request();
            await lib_1.UtilsTerminal.pressAnyKeyToContinueAsync({
                message: 'Port deleted successfully. Press any key to continue...',
            });
            return;
        }
        catch (error) {
            await lib_1.UtilsTerminal.pressAnyKeyToContinueAsync({
                message: 'Something went wrong. Press any key to continue...',
            });
            return;
        }
        //#endregion
    }
    //#endregion
    //#region methods / edit port process
    async editPortTerminalUiProcess() {
        //#region @backendFunc
        const ctrl = await this.worker.getRemoteControllerFor({
            methodOptions: {
                calledFrom: 'editPortTerminalUiProcess',
            },
        });
        const portsTakeByOs = (await ctrl.getPortsByStatus('assigned-taken-by-os').request()).body.json;
        const selectedPort = await this.selectPortProcess(portsTakeByOs, 'Select port to edit');
        if (!selectedPort) {
            return;
        }
        while (true) {
            const newDescription = await lib_1.UtilsTerminal.input({
                question: 'Enter new unique Id (description)',
                defaultValue: selectedPort.serviceId,
            });
            try {
                const updatePort = (await ctrl
                    .updatePortUniqueId(selectedPort.port, encodeURIComponent(newDescription))
                    .request()).body.json;
                await lib_1.UtilsTerminal.pressAnyKeyToContinueAsync({
                    message: `Port ${updatePort.port} edited successfully. Press any key to continue...`,
                });
                return;
            }
            catch (error) {
                await lib_1.UtilsTerminal.pressAnyKeyToContinueAsync({
                    message: 'Something went wrong. Press any key to continue...',
                });
                return;
            }
        }
        //#endregion
    }
    //#endregion
    //#region methods / get worker terminal actions
    getWorkerTerminalActions(options) {
        //#region @backendFunc
        options = options || {};
        const additionalActions = {};
        for (const portStatus of index_1.PortStatusArr) {
            additionalActions[`show${lib_1._.capitalize(portStatus)}Ports`] = {
                name: `Show all "${portStatus}" ports`,
                action: async () => {
                    await this.displayItemsForPortsStatus(portStatus);
                },
            };
        }
        return {
            ...this.chooseAction,
            previewPorts: {
                name: 'Preview all ports',
                action: async () => {
                    while (true) {
                        const { selected } = await lib_1.UtilsTerminal.selectActionAndExecute({
                            ...this.backAction,
                            ...additionalActions,
                        }, {
                            autocomplete: false,
                            question: 'Select ports to preview',
                        });
                        if (selected === 'back') {
                            break;
                        }
                    }
                },
            },
            editAddTakeByOsPort: {
                name: 'Edit/Add/Delete "Take by os ports"',
                action: async () => {
                    await this.crudMenuForTakeByOsPorts();
                },
            },
            ...super.getWorkerTerminalActions({ chooseAction: false, ...options }),
        };
        //#endregion
    }
    //#endregion
    //#region methods / display menu with items
    async displayItemsForPortsStatus(status) {
        //#region @backendFunc
        while (true) {
            try {
                const controller = await this.worker.getRemoteControllerFor({
                    methodOptions: {
                        calledFrom: `displayItemsForPortsStatus:${status}`,
                    },
                });
                const portsData = await controller.getPortsByStatus(status).request();
                const ports = portsData.body.json.map(c => c.titleOnList);
                if (ports.length === 0) {
                    lib_1.Helpers.info(`

            No ports with status "${status}" as taken by os yet...

            `);
                    await lib_1.UtilsTerminal.pressAnyKeyToContinueAsync({
                        message: 'Press any key to continue',
                    });
                }
                else {
                    await lib_1.UtilsTerminal.previewLongList(ports.join('\n'));
                }
                break;
            }
            catch (error) {
                console.error(error);
                if (!(await lib_1.UtilsTerminal.pressAnyKeyToTryAgainErrorOccurred(error))) {
                    break;
                }
            }
        }
        //#endregion
    }
    //#endregion
    //#region methods / get new port to add
    async getNewPortToAdd() {
        //#region @backendFunc
        const ctrl = await this.worker.getRemoteControllerFor({
            methodOptions: {
                calledFrom: 'getNewPortToAdd',
            },
        });
        let portToAdd;
        while (true) {
            const getFreePort = (await ctrl.getFirstFreePort().request()).body.json
                .port;
            const inputNumber = await lib_1.UtilsTerminal.input({
                defaultValue: getFreePort?.toString(),
                question: 'Enter port number',
            });
            portToAdd = Number(inputNumber);
            const portIsNumber = !isNaN(portToAdd);
            const portInRange = portToAdd >= ctrl.START_PORT && portToAdd <= ctrl.END_PORT;
            if (!portIsNumber || !portInRange) {
                {
                    if (await lib_1.UtilsTerminal.confirm({
                        message: `Port number is not valid. Do you want to try again?`,
                        defaultValue: true,
                    })) {
                        continue;
                    }
                    else {
                        return;
                    }
                }
            }
            if (portIsNumber && portInRange) {
                break;
            }
        }
        return portToAdd;
        //#endregion
    }
}
exports.TcpUdpPortsTerminalUI = TcpUdpPortsTerminalUI;
//# sourceMappingURL=tcp-upd-ports-terminal-ui.js.map