var r = require('rethinkdb')
var Promise = require('bluebird')

var db = require('./')
var wire = require('../wire')
var wireutil = require('../wire/util')

var dbapi = Object.create(null)

dbapi.close = function(options) {
  return db.close(options)
}

dbapi.saveUserAfterLogin = function(user) {
  return db.run(r.table('users').get(user.email).update({
      name: user.name
    , lastLoggedInAt: r.now()
    }))
    .then(function(stats) {
      if (stats.skipped) {
        return db.run(r.table('users').insert({
          email: user.email
        , name: user.name
        , group: wireutil.makePrivateChannel()
        , lastLoggedInAt: r.now()
        , createdAt: r.now()
        }))
      }
      return stats
    })
}

dbapi.loadUser = function(email) {
  return db.run(r.table('users').get(email))
}

dbapi.loadGroupMembers = function(email) {
  return db.run(r.table('devices').getAll(email, {
      index: 'ownerEmail'
    })('serial'))
}

dbapi.saveDeviceLog = function(serial, entry) {
  return db.run(r.table('logs').insert({
    serial: entry.serial
  , timestamp: r.epochTime(entry.timestamp)
  , priority: entry.priority
  , tag: entry.tag
  , pid: entry.pid
  , message: entry.message
  }))
}

dbapi.saveDevice = function(serial, device) {
  return db.run(r.table('devices').insert({
      serial: serial
    , present: true
    , provider: device.provider
    , owner: null
    , status: device.status
    , statusChangedAt: r.now()
    , createdAt: r.now()
    , lastHeartbeatAt: r.now()
    }
  , {
      upsert: true
    }))
}

dbapi.saveDeviceStatus = function(serial, status) {
  return db.run(r.table('devices').get(serial).update({
    status: status
  , statusChangedAt: r.now()
  }))
}

dbapi.setDeviceOwner = function(serial, owner) {
  return db.run(r.table('devices').get(serial).update({
    owner: owner
  }))
}

dbapi.unsetDeviceOwner = function(serial, owner) {
  return db.run(r.table('devices').get(serial).update({
    owner: null
  }))
}

dbapi.setDeviceAbsent = function(serial) {
  return db.run(r.table('devices').get(serial).update({
    present: false
  , lastHeartbeatAt: null
  }))
}

dbapi.setDeviceChannel = function(serial, channel) {
  return db.run(r.table('devices').get(serial).update({
    channel: channel
  }))
}

dbapi.saveDeviceIdentity = function(serial, identity) {
  return db.run(r.table('devices').get(serial).update({
    platform: identity.platform
  , manufacturer: identity.manufacturer
  , operator: identity.operator
  , model: identity.model
  , version: identity.version
  , abi: identity.abi
  , sdk: identity.sdk
  , display: identity.display
  }))
}

dbapi.loadDevices = function() {
  return db.run(r.table('devices'))
}

dbapi.loadDevice = function(serial) {
  return db.run(r.table('devices').get(serial))
}

dbapi.updateDeviceHeartbeat = function(serial) {
  return db.run(
    r.table('devices').get(serial).update({
      lastHeartbeatAt: r.now()
    })
  , {
      noreply: true
    , durability: 'soft'
    }
  )
}

dbapi.getDeadDevices = function(timeout) {
  return db.run(
    r.table('devices')
      .between(null, r.now().sub(timeout / 1000), {
        index: 'lastHeartbeatAt'
      })
      .pluck('serial')
  )
}

module.exports = dbapi
