'use strict'
/*
  Open Rowing Monitor, https://github.com/laberning/openrowingmonitor

  Implementation of the AdditionalStatus as defined in:
  https://www.concept2.co.uk/files/pdf/us/monitors/PM5_BluetoothSmartInterfaceDefinition.pdf
*/
import bleno from '@abandonware/bleno'
import { getFullUUID } from '../Pm5Constants.js'
import log from 'loglevel'
import BufferBuilder from '../../BufferBuilder.js'

export default class AdditionalStatus extends bleno.Characteristic {
  constructor (multiplexedCharacteristic) {
    super({
      // id for AdditionalStatus as defined in the spec
      uuid: getFullUUID('0032'),
      value: null,
      properties: ['notify']
    })
    this._updateValueCallback = null
    this._multiplexedCharacteristic = multiplexedCharacteristic
  }

  onSubscribe (maxValueSize, updateValueCallback) {
    log.debug(`AdditionalStatus - central subscribed with maxSize: ${maxValueSize}`)
    this._updateValueCallback = updateValueCallback
    return this.RESULT_SUCCESS
  }

  onUnsubscribe () {
    log.debug('AdditionalStatus - central unsubscribed')
    this._updateValueCallback = null
    return this.RESULT_UNLIKELY_ERROR
  }

  notify (data) {
    if (this._updateValueCallback || this._multiplexedCharacteristic.centralSubscribed()) {
      const bufferBuilder = new BufferBuilder()
      // elapsedTime: UInt24LE in 0.01 sec
      bufferBuilder.writeUInt24LE(Math.round(data.durationTotal * 100))
      // speed: UInt16LE in 0.001 m/sec
      bufferBuilder.writeUInt16LE(Math.round(data.speed * 1000 / 3.6))
      // strokeRate: UInt8 in strokes/min
      bufferBuilder.writeUInt8(Math.round(data.strokesPerMinute))
      // heartrate: UInt8 in bpm, 255 if invalid
      bufferBuilder.writeUInt8(Math.round(data.heartrate))
      // currentPace: UInt16LE in 0.01 sec/500m
      // if split is infinite (i.e. while pausing), use the highest possible number
      bufferBuilder.writeUInt16LE(data.split !== Infinity ? Math.round(data.split * 100) : 0xFFFF)
      // averagePace: UInt16LE in 0.01 sec/500m
      let averagePace = 0
      if (data.distanceTotal && data.distanceTotal !== 0) {
        averagePace = data.durationTotal / data.distanceTotal * 500
      }
      bufferBuilder.writeUInt16LE(Math.round(averagePace * 100))
      // restDistance: UInt16LE
      bufferBuilder.writeUInt16LE(0)
      // restTime: UInt24LE in 0.01 sec
      bufferBuilder.writeUInt24LE(0 * 100)
      if (!this._updateValueCallback) {
      // the multiplexer uses a slightly different format for the AdditionalStatus
      // it adds averagePower before the ergMachineType
      // averagePower: UInt16LE in watts
        bufferBuilder.writeUInt16LE(Math.round(data.power))
      }
      // ergMachineType: 0 TYPE_STATIC_D
      bufferBuilder.writeUInt8(0)

      if (this._updateValueCallback) {
        this._updateValueCallback(bufferBuilder.getBuffer())
      } else {
        this._multiplexedCharacteristic.notify(0x32, bufferBuilder.getBuffer())
      }
      return this.RESULT_SUCCESS
    }
  }
}
