<commit_before>/**
 * Created by Praveen on 13/10/2015.
 *
 * @flow
 */

import { APIInterface } from './api';
import * as constants from '../constants/event-name-constants';
import { hasError } from './payload';
import * as stringUtils from '../utils/string-utils';

export class WebsocketAPI {
    constructor(store) {
        this.api = new APIInterface(
            store,
            this.onData.bind(this),
            this.onDataPublished.bind(this)
        );
        this.connectedClients = {};
    }

    onDataPublished(payload) {
        for(let path in this.connectedClients) {
            if(this.connectedClients.hasOwnProperty(path)) {
                let ws = this.connectedClients[path];
                ws.send(JSON.stringify( {
                    'event': constants.AX_ATTRIBUTE_CACHE_PUBLISH,
                    'data': payload
                }));
            }
        }
    }

    getDevices(ws) {
        let devicesWithAttributes = this.api.getDevices();
        let response = JSON.stringify({
            'event': constants.AX_CLIENT_DEVICES_GET_ALL,
            'data': devicesWithAttributes
        });
        console.log(response);
        ws.send(response);
    }

    connect (ws, data) {
        let options = data;
        this.api.connect(options, (payload) => {
            let path = stringUtils.parseSerialPath(options.path);
            this.connectedClients[path] = ws;

            if(!hasError(payload)) {
                ws.send(JSON.stringify({
                    'event': constants.AX_DEVICE_CONNECT,
                    'data': payload
                }));

            } else {
                console.log("There is an error");
                console.log(payload);
                ws.send(JSON.stringify({
                    'event': constants.AX_DEVICE_CONNECT,
                    'data': payload
                }));
            }
        });
    }

    write (ws, options) {
        this.api.write(options, (payload) => {
            console.log("Writing back");
            console.log(payload);
            ws.send(JSON.stringify({
                'event': constants.AX_DEVICE_WRITE,
                'data': payload
            }));
        });
    }

    disconnect (ws, options) {
        this.api.disconnect(options, (payload) => {
            let path = stringUtils.parseSerialPath(options.path);
            delete this.connectedClients[path];
            ws.send(JSON.stringify({
                'event': constants.AX_DEVICE_DISCONNECT,
                'data': payload
            }));
        });
    }

    onData(response) {
        console.log(response);
        let path = stringUtils.parseSerialPath(response.path);
        let ws = this.connectedClients[path];

        if (ws.readyState === ws.OPEN) {
            ws.send(JSON.stringify( {
                'event': constants.AX_CLIENT_DATA,
                'data': response
            }));

        } else {
            console.warn('Web socket status not open -> ' + ws.readyState);
        }
    }

    /**
     *  See AttributesAPI
     */
    publish(ws, options) {
        let {devicePath, attributeKey, attributeVal} = options;
        let payload = this.api.publish(devicePath, attributeKey, attributeVal);
        ws.send(JSON.stringify({
            'event': constants.AX_DEVICE_ATTRIBUTE_PUBLISH,
            'data': payload
        }));
    }

    _disconnectOnClose(options) {
        this.api.disconnect(options, (payload) => {
            if(hasError(payload)) {
                console.error('Error on closing the connection ' + options.path);

            } else {
                console.info('Closed path ' + options.path);
            }

        });
    }

    _getDevicePathsConnectedToWebSocketClient(ws): Array<String> {
        let paths: Array<String> = [];
        for(let key in this.connectedClients) {
            if(this.connectedClients.hasOwnProperty(key)) {
                if(ws.id === this.connectedClients[key].id) {
                    paths.push(key);
                }
            }
        }
        return paths;
    }

    _cleanUpOnWebSocketConnectionClosed(ws) {
        let paths: Array<String> = this._getDevicePathsConnectedToWebSocketClient(ws);

        for(let i=0; i<paths.length; i++) {
            let options = {
                'path': stringUtils.constructSerialPath(paths[i])
            };
            this._disconnectOnClose(options);
        }
    }
}

export function websocketSetup(wss, store) {

    console.log('Setting up websocket');
    var webSocketAPI = new WebsocketAPI(store);

    wss.on('connection', (ws) => {
        console.log('Connected');

        ws.on('message', (message) => {
            console.log(message);<commit_msg>added some log messages<commit_after>/**
 * Created by Praveen on 13/10/2015.
 *
 * @flow
 */

import { APIInterface } from './api';
import * as constants from '../constants/event-name-constants';
import { hasError } from './payload';
import * as stringUtils from '../utils/string-utils';

export class WebsocketAPI {
    constructor(store) {
        this.api = new APIInterface(
            store,
            this.onData.bind(this),
            this.onDataPublished.bind(this)
        );
        this.connectedClients = {};
    }

    onDataPublished(payload) {
        for(let path in this.connectedClients) {
            if(this.connectedClients.hasOwnProperty(path)) {
                let ws = this.connectedClients[path];
                ws.send(JSON.stringify( {
                    'event': constants.AX_ATTRIBUTE_CACHE_PUBLISH,
                    'data': payload
                }));
            }
        }
    }

    getDevices(ws) {
        let devicesWithAttributes = this.api.getDevices();
        let response = JSON.stringify({
            'event': constants.AX_CLIENT_DEVICES_GET_ALL,
            'data': devicesWithAttributes
        });
        console.log(response);
        ws.send(response);
    }

    connect (ws, data) {
        let options = data;
        this.api.connect(options, (payload) => {
            let path = stringUtils.parseSerialPath(options.path);
            this.connectedClients[path] = ws;

            if(!hasError(payload)) {
                ws.send(JSON.stringify({
                    'event': constants.AX_DEVICE_CONNECT,
                    'data': payload
                }));

            } else {
                console.log("There is an error");
                console.log(payload);
                ws.send(JSON.stringify({
                    'event': constants.AX_DEVICE_CONNECT,
                    'data': payload
                }));
            }
        });
    }

    write (ws, options) {
        this.api.write(options, (payload) => {
            console.log("Writing back");
            console.log(payload);
            ws.send(JSON.stringify({
                'event': constants.AX_DEVICE_WRITE,
                'data': payload
            }));
        });
    }

    disconnect (ws, options) {
        this.api.disconnect(options, (payload) => {
            let path = stringUtils.parseSerialPath(options.path);
            delete this.connectedClients[path];
            ws.send(JSON.stringify({
                'event': constants.AX_DEVICE_DISCONNECT,
                'data': payload
            }));
        });
    }

    onData(response) {
        console.log(response);
        let path = stringUtils.parseSerialPath(response.path);
        let ws = this.connectedClients[path];

        if (ws.readyState === ws.OPEN) {
            ws.send(JSON.stringify( {
                'event': constants.AX_CLIENT_DATA,
                'data': response
            }));

        } else {
            console.warn('Web socket status not open -> ' + ws.readyState);
        }
    }

    /**
     *  See AttributesAPI
     */
    publish(ws, options) {
        let {devicePath, attributeKey, attributeVal} = options;
        let payload = this.api.publish(devicePath, attributeKey, attributeVal);
        ws.send(JSON.stringify({
            'event': constants.AX_DEVICE_ATTRIBUTE_PUBLISH,
            'data': payload
        }));
    }

    _disconnectOnClose(options) {
        this.api.disconnect(options, (payload) => {
            if(hasError(payload)) {
                console.error('Error on closing the connection ' + options.path);

            } else {
                console.info('Closed path ' + options.path);
            }
        });
    }

    _getDevicePathsConnectedToWebSocketClient(ws): Array<String> {
        let paths: Array<String> = [];
        for(let key in this.connectedClients) {
            if(this.connectedClients.hasOwnProperty(key)) {
                if(ws.id === this.connectedClients[key].id) {
                    paths.push(key);
                }
            }
        }
        return paths;
    }

    _cleanUpOnWebSocketConnectionClosed(ws) {
        let paths: Array<String> = this._getDevicePathsConnectedToWebSocketClient(ws);

        for(let i=0; i<paths.length; i++) {
            let options = {
                'path': stringUtils.constructSerialPath(paths[i])
            };
            this._disconnectOnClose(options);
        }
    }
}

export function websocketSetup(wss, store) {

    console.log('Setting up Websocket API');
    var webSocketAPI = new WebsocketAPI(store);

    wss.on('connection', (ws) => {
        console.log('Connected');

        ws.on('message', (message) => {
            console.log(message);
{'fraction_non_alphanumeric': 0.12313866300559721, 'fraction_numerical': 0.0019009399091773154, 'mean_word_length': 1.6827195467422096, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7286112', 'n_tokens_mistral': 2671, 'n_tokens_neox': 2555, 'n_words': 449}