/*********************************************************************
 *
 *  $Id: app.ts 32624 2018-10-10 13:23:29Z seb $
 *
 *  Yoctopuce TypeScript library example
 *
 *  You can find more information on our web site:
 *   EcmaScript API Reference:
 *      https://www.yoctopuce.com/EN/doc/reference/yoctolib-ecmascript-EN.html
 *
 *********************************************************************/

import { YAPI, YAPIContext, YErrorMsg, YModule, YSensor, YMeasure } from 'yoctolib-cjs/yocto_api_nodejs.js';
import * as http from 'http';
import WebSocket from 'ws';

class DataPoint {
    public name: string;
    public time: number;
    public value: number;

    constructor(name: string, timestamp: number, value: number)
    {
        this.name = name;
        this.time = timestamp;
        this.value = value;
    }
}

let Data: DataPoint[] = [];

async function sensorCallback(sensor: YSensor, measure: YMeasure): Promise<void>
{
    Data.push(new DataPoint(
        await sensor.get_hardwareId(),
        await measure.get_endTimeUTC(),
        await measure.get_averageValue()));
}

async function HttpCallbackHandler(message: http.IncomingMessage, response: http.ServerResponse): Promise<void>
{
    // HTTP requests from the web browsers land here
    response.writeHead(200, {'Content-Type': 'text/html'});
    response.write('time;sensor;value<br>\n');
    for(let i: number = 0; i < Data.length; i++) {
        response.write(Data[i].time + ";" +
            Data[i].name + ";" +
            Data[i].value + "<br>\n");
    }
    response.end();
}

async function WebSocketCallbackHandler(ws: WebSocket): Promise<void>
{
    // WebSocket connections from the YoctoHubs land here
    console.log('Incoming WebSocket connection!');
    let errmsg: YErrorMsg = new YErrorMsg();
    let yctx: YAPIContext = new YAPIContext();
    if(await yctx.RegisterHubWebSocketCallback(ws as any, errmsg, 'MY-WEBSOCKET-PASSWORD!') != YAPI.SUCCESS) {
        console.log('WebSocket callback error: ' + errmsg);
        yctx.FreeAPI();
        return;
    }
    try {
        await yctx.UpdateDeviceList(errmsg);
        let sensor: YSensor | null = YSensor.FirstSensorInContext(yctx);
        while(sensor != null) {
            console.log('Sensor: ' + (await sensor.get_hardwareId()));
            await sensor.set_reportFrequency("6/m");
            await sensor.registerTimedReportCallback(sensorCallback);
            sensor = sensor.nextSensor()
        }
        while(ws.readyState != ws.CLOSED) {
            await yctx.Sleep(1000, errmsg);
        }
    } catch(e) {
        console.log('Exception in WebSocket handler:');
        console.log(e);
    }
    console.log('Websocket disconnected');
    await yctx.FreeAPI();
}

YAPI.LogUnhandledPromiseRejections();

// We create an HTTP server...
http.createServer(HttpCallbackHandler).listen(8080);

// ... and we create a WebSocket server
let wss: WebSocket.Server = new WebSocket.Server({ port: 8044 });
wss.on('connection', WebSocketCallbackHandler);

console.log('Node.js Web HTTP server running on http://...:8080/');
console.log('Node.js Websocket server running on http://...:8044/');
