//#region imports
import { ___NS__capitalize, Helpers__NS__info, UtilsTerminal__NS__confirm, UtilsTerminal__NS__input, UtilsTerminal__NS__pressAnyKeyToContinueAsync, UtilsTerminal__NS__pressAnyKeyToTryAgainErrorOccurred, UtilsTerminal__NS__previewLongList, UtilsTerminal__NS__select, UtilsTerminal__NS__selectActionAndExecute } from 'tnp-core/lib-prod';
import { PortStatusArr } from '../../index';
import { BaseCliWorkerTerminalUI } from '../classes/base-cli-worker/base-cli-worker-terminal-ui';
//#endregion
export class TcpUdpPortsTerminalUI extends 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 UtilsTerminal__NS__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 UtilsTerminal__NS__input({
                defaultValue: `my-service-on-port-${portToAdd}`,
                question: 'Enter service unique description',
            });
            try {
                await UtilsTerminal__NS__pressAnyKeyToContinueAsync();
                const addedPort = (await ctrl
                    .addTakeByOsPort(portToAdd, encodeURIComponent(uniqueId))
                    .request()).body.json;
                await UtilsTerminal__NS__pressAnyKeyToContinueAsync({
                    message: `Port ${addedPort.port} added successfully. Press any key to continue...`,
                });
                return;
            }
            catch (error) {
                await UtilsTerminal__NS__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 UtilsTerminal__NS__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 UtilsTerminal__NS__pressAnyKeyToContinueAsync({
                message: 'Port deleted successfully. Press any key to continue...',
            });
            return;
        }
        catch (error) {
            await UtilsTerminal__NS__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 UtilsTerminal__NS__input({
                question: 'Enter new unique Id (description)',
                defaultValue: selectedPort.serviceId,
            });
            try {
                const updatePort = (await ctrl
                    .updatePortUniqueId(selectedPort.port, encodeURIComponent(newDescription))
                    .request()).body.json;
                await UtilsTerminal__NS__pressAnyKeyToContinueAsync({
                    message: `Port ${updatePort.port} edited successfully. Press any key to continue...`,
                });
                return;
            }
            catch (error) {
                await UtilsTerminal__NS__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 PortStatusArr) {
            additionalActions[`show${___NS__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 UtilsTerminal__NS__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) {
                    Helpers__NS__info(`

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

            `);
                    await UtilsTerminal__NS__pressAnyKeyToContinueAsync({
                        message: 'Press any key to continue',
                    });
                }
                else {
                    await UtilsTerminal__NS__previewLongList(ports.join('\n'));
                }
                break;
            }
            catch (error) {
                console.error(error);
                if (!(await UtilsTerminal__NS__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 UtilsTerminal__NS__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 UtilsTerminal__NS__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
    }
}
//# sourceMappingURL=c:/Users/darek/projects/npm/taon-dev/tnp-helpers/dist-nocutsrc-prod/lib/base/tcp-udp-ports/tcp-upd-ports-terminal-ui.js.map