'use strict'

var R = require('ramda')

var db = null

function init (_db) {
  db = _db
}

function toInt10 (str) { return parseInt(str, 10) }

function jsonParse (event) {
  return R.assoc('note', JSON.parse(event.note), event)
}

function sameState (a, b) {
  return a.note.sessionId === b.note.sessionId && a.note.state === b.note.state
}

function checkPing (deviceEvents) {
  var sortedEvents = R.sortBy(R.compose(toInt10, R.prop('device_time')), R.map(jsonParse, deviceEvents))
  var lastEvent = R.last(sortedEvents)
  var NETWORK_DOWN_TIME = 2 * 60 * 1000

  if (!lastEvent) {
    console.log('No data for device')
    return
  }

  if (lastEvent.age > NETWORK_DOWN_TIME) {
    return console.log('Device not reachable [ALERT]')
  }

  console.log('Device reachable [OK]')
}

function checkStuckScreen (deviceEvents) {
  var sortedEvents = R.sortBy(R.compose(toInt10, R.prop('device_time')), R.map(jsonParse, deviceEvents))
  var noRepeatEvents = R.dropRepeatsWith(sameState, sortedEvents)
  var lastEvent = R.last(noRepeatEvents)
  var IDLE_STATES = ['idle', 'dualIdle']
  var STALE_STATE = 60 * 1000

  if (!lastEvent) {
    console.log('No data for device')
    return
  }

  var state = lastEvent.note.state
  if (R.contains(state, IDLE_STATES)) {
    console.log('Machine is idle [OK]')
    return
  }

  console.log(lastEvent.age)
  if (lastEvent.age > STALE_STATE) {
    console.log('Stale state: ' + state + ' [ALERT]')
    return
  }

  console.log('[OK]')
}

function checkStatus () {
/*
  - Fetch devices from devices table
  - Fetch all machine_events into memory
  - For each device, verify the following:
    - stuck on screen
      - last screen is >5m stale and is not idle screen
      - report stuck on screen and name of screen
    - not scanning qr codes?
    - low bitcoins -- need a separate strategy, but server has this info
      - var fiatBalance = plugins.fiatBalance();
    - machine isn't pinging server
*/
  db.devices(function (err, devices) {
    if (err) return console.error(err)

    db.machineEvents(function (err, events) {
      if (err) return console.error(err)

      devices.rows.forEach(function (deviceRow) {
        var deviceFingerprint = deviceRow.fingerprint
        var deviceEvents = events.rows.filter(function (eventRow) {
          return eventRow.device_fingerprint === deviceFingerprint
        })

        console.log('DEVICE: ' + deviceRow.fingerprint)
        checkStuckScreen(deviceEvents)
        checkPing(deviceEvents)
      })
    })
  })
}

var _db = require('./postgresql_interface')
var connectionString = 'postgres://lamassu:lamassu@localhost/lamassu'
_db.init(connectionString)

init(_db)

checkStatus()

// TODO: How to know which alerts have been sent?
// Send alert every 10m while alert state
// Remember last sent alert in memory

@@ -46,16 +46,38 @@
 b = null
+%0Avar getBalance = null
 %0A%0Afuncti
@@ -88,16 +88,29 @@
 nit (_db
+, _getBalance
 ) %7B%0A  db
@@ -116,16 +116,43 @@
 b = _db%0A
+  getBalance = _getBalance%0A
 %7D%0A%0Afunct
@@ -394,24 +394,236 @@
 te.state%0A%7D%0A%0A
+function checkBalance () %7B%0A  var LOW_BALANCE_THRESHOLD = 10%0A  if (getBalance() %3C LOW_BALANCE_THRESHOLD) %7B%0A    return console.log('Bitcoin balance is low %5BALERT%5D')%0A  %7D%0A%0A  console.log('Bitcoin balance ok %5BOK%5D')%0A%7D%0A%0A
 function che
@@ -1897,17 +1897,17 @@
 ng:%0A    
--
+v
  stuck o
@@ -2176,17 +2176,17 @@
 ();%0A    
--
+v
  machine
@@ -2211,10 +2211,69 @@
 ver%0A
-*/
+    - jam checking, need report from l-m%0A*/%0A  checkBalance()%0A
 %0A  d
@@ -2952,16 +2952,64 @@
 amassu'%0A
+%0Avar _getBalance = function () %7B%0A  return 12%0A%7D%0A%0A
 _db.init
@@ -3031,17 +3031,16 @@
 ng)%0A
-%0A
 init(_db
 )%0A%0Ac
@@ -3035,16 +3035,29 @@
 init(_db
+, _getBalance
 )%0A%0Acheck

add bitcoin balance check