/*
    ! /servers/gateway/functions.js – Central Gateway Server Functions
    ? This modules exports the functionality for the express gateway server
*/

// % import nodejs dependencies
const WebSocket = require('ws');

// % core variables
const ip = process.env.INTERNAL_HOST_IP;
const port = process.env.INTERNAL_GATEWAY_PORT;

// % create a reference for the websocket client
let wsClient = null;

// % create an event emitter for the gateway
const EventEmitter = require('events');
const gatewayEvents = new EventEmitter();

// $ helper: send messages through websocket
function sendToWs(payload) {
    if (wsClient && wsClient.readyState === WebSocket.OPEN) {
        wsClient.send(JSON.stringify(payload));
    } else {
        console.error('WebSocket not connected.');
    }
}

// $ server start function
async function boot(server) {
    // ~ start express server
    server.listen(port, ip, () => {
        console.info(`Express server is now running on http://${ip}:${port}`);
    });

    // ~ connect to the websocket server
    const wsUrl = `ws://${process.env.INTERNAL_HOST_IP}:${process.env.INTERNAL_WEBSOCKET_PORT}?key=${process.env.INTERNAL_SECRET}&codename=gateway`;
    wsClient = new WebSocket(wsUrl);

    wsClient.on('open', () => {
        console.info('Connected to central websocket server');
    });

    wsClient.on('message', (data) => {
        const msg = JSON.parse(data);
        gatewayEvents.emit('ws_message', msg);
    });

    wsClient.on('error', (err) => {
        console.error('WebSocket error:', err.message);
    });

    // ~ return running express server reference
    return server;
};

// $ server shutdown function
async function shutdown(server) {
    // ~ close websocket server
    if (wsClient) {
        wsClient.close();
        wsClient = null;
    }

    // ~ shutdown running express server
    return new Promise((resolve) => {
        server.close(() => {
            console.info('Express server shut down.');
            resolve(server);
        });
    });
};

// $ server restart function
async function restart(server) {
    // ~ shutdown the running express server
    await shutdown(server);

    // ~ restart the express server
    await boot(server);

    // ~ return the server reference
    return server;
};

// $ server status function
async function status(server) {
    // ~ get and return server listening status
    return server.listening ? 'online' : 'offline';
};

// § export server functions module
module.exports = { boot, shutdown, restart, status, sendToWs, gatewayEvents };