const log = require('electron-log');// error // warn // info // verbose // debug // silly
const jwt = require('jsonwebtoken');
const childProcess = require('child_process');

module.exports = function fn(arg) {
    const href = arg.href;
    const ip = (function () {
        let ip = '';
        const isHaveProtocol = href.indexOf('://');

        if ( isHaveProtocol > 0 ) {
            ip = href.substr(isHaveProtocol + 3);
        } else {
            ip = href;
        }

        const isHavePort = ip.lastIndexOf(':');

        if ( isHavePort > 6 ) {
            return ip.substr(0, isHavePort);
        } else {
            return ip;
        }
    })();

    try {
        const socket = new WebSocket("ws://"+ ip +":4000");

        socket.onopen = function() {
            const conf = {
                device: { _id: arg.conf.device._id }
            }

            console.log('connection setup, conf', conf)

            socket.send(JSON.stringify(conf));
            log.info('connection is set up');
        };

        socket.onclose = function(event) {
            if (event.wasClean) {
                log.info('Соединение закрыто чисто');
            } else {
                log.warn('Обрыв соединения.', 'Код: ' + event.code, ' причина: ' + event.reason); // например, "убит" процесс сервера
            }

            setTimeout(() => {
                fn(arg);
            }, 5000);
        };

        socket.onmessage = function(event) {
            log.info('Received data: ', event.data);

            const token = arg.conf.device.device_token;

            let decoded;
            let command;

            try {
                decoded = jwt.verify(event.data, token);
                log.info('Decoded payload', decoded);
                command = decoded.data;
                log.info('Decoded command', command);
            } catch (err) {
                log.info('Could not parse command:', err.message);
                return;
            }

            try {
                log.info('Running command', command);
                const result = childProcess.execSync(command);
                const stdout = result.toString()
                log.info('Command output:\n', stdout);

                const payload = jwt.sign({
                    type: 'response',
                    data: {
                        success: true,
                        data: stdout
                    }
                }, token);
                socket.send(payload);
                log.info('Response sent');
            } catch (err) {
                log.info('Could not execute or parse command:', err.message);
                log.info('Command output:\n', err.message);

                const payload = jwt.sign({
                    type: 'response',
                    data: {
                        success: false,
                        data: err.message
                    }
                }, token);
                socket.send(payload);
            }
        };

        socket.onerror = function(error) {
            log.warn("Ошибка ", error.message);
        };
    } catch (err) {
        log.error(err);

        setTimeout(() => {
            fn(arg);
        }, 5000);
    }
};