import SwimTrackerWebsocketConnection from "../data_processing/SwimTrackerWebsocketConnection.js";
import yargs from 'yargs';
import WS from 'ws';
import { SerialPort } from 'serialport'
import { ReadlineParser } from '@serialport/parser-readline'
import chalk from 'chalk';


/**
 * Opens serial port and calls provided function on each line
 * 
 * @param {string} serialPortPath 
 * @param {(str) => any} onLineReceived
 */
function openSerialConnection(serialPortPath, onLineReceived) {
  const port = new SerialPort({
    path: serialPortPath,
    baudRate: 115200
  });
  const parser = port.pipe(new ReadlineParser());
  parser.on('data', onLineReceived);
}

function basicTest(deviceIpOrHostname, serialPort) {

  let lastHostLog = undefined;
  let lastDeviceLog = undefined;

  function log(color, main, startCol) {
    if(lastHostLog === undefined)
      lastHostLog = Date.now();
    const currentTime = Date.now();
    const dt = currentTime - lastHostLog;
    lastHostLog = currentTime;

    console.log(color((startCol).padEnd(9), "|", String(dt).padStart(5), "|", main));
  }

  function logDeviceTime(color, main, column1, time) {
    if(lastDeviceLog === undefined)
      lastDeviceLog = time;
    const dt = time - lastDeviceLog;
    lastDeviceLog = time;
    
    console.log(color((column1).padEnd(9), "|", String(dt).padStart(5), "|", main));
  }

  const onStarted = (sessionid) => { log(chalk.yellow, "Session started " + sessionid, "WS Msg") }; 
  const onStopped = () => { log(chalk.yellow, "Session stopped", "WS Msg") };
  const onWifiStateInfo = (wifiInfo) => { log(chalk.cyan, JSON.stringify(wifiInfo), "WS Wifi") };
  const onWebsocketLog = (logMsg) => {logDeviceTime(chalk.blue, logMsg.msg, "WS Log", String(logMsg.time))};
  const onDisconnect = () => { log(chalk.red, "Disconnected", "WS Msg") };
  const onConnect = () => { 
      log(chalk.blue,"Connected to device", "WS Msg") 
      conn.sendLogStreamStartCommand();
  };

  let data = [];

  const onNewMeasurementData = (newDataAsUint16Arr) => {
    const arr = Array.from(newDataAsUint16Arr);
    newDataAsUint16Arr.forEach(element => {
      data.push(element);
    });

    const existing = "(" + String(data.length).padStart(5) + ") ";
    if(arr.length > 5) {
      log(chalk.yellow, existing + "Bulk " + arr.length + " measurements", "WS Data");
    } else {
      log(chalk.gray, existing + JSON.stringify(Array.from(newDataAsUint16Arr)), "WS Data");
    }
  };

  if(serialPort) {
     openSerialConnection(serialPort, (receivedLine) => {
      log(chalk.gray, receivedLine, "Serial");
     });
  }

  const conn = new SwimTrackerWebsocketConnection(deviceIpOrHostname, onNewMeasurementData, onStarted, onStopped,
    onWifiStateInfo, onConnect, onDisconnect,
    { WebSocket: WS });
  conn.onLogMessage = onWebsocketLog;    
}


basicTest("192.168.178.56", "/dev/ttyUSB1");
//basicTest("192.168.178.56", undefined);

// {"speeds":[0.4, -0.3],"durations":[1500, 1500]}

/*
Testrun:
  Captures:
    - streamed data from websocket
    - log messages from serial port
    - output of serial port 
  File format:
    - timestamp of aquisition
    - type 
      - websocket message
      - serial port line
  Logging:
    - websocket errors always

  Commands:
    - replay file
    - data as csv
*/
