'use strict'

const async = require('async')
const config = require('./config')
const logger = require('./logger')
const moment = require('moment')

class UpdateDirtyNoteJob {
  constructor (realtime) {
    this.realtime = realtime
  }

  start () {
    setInterval(this.updateDirtyNote.bind(this), 1000)
  }

  updateDirtyNote () {
    const notes = this.realtime.getNotePool()
    async.each(Object.keys(notes), (key, callback) => {
      const note = notes[key]
      if (!note.server.isDirty) return callback(null, null)

      if (config.debug) logger.info('updater found dirty note: ' + key)
      note.server.isDirty = false
      this.realtime.updateNote(note, (err, _note) => {
        // handle when note already been clean up
        if (!notes[key] || !notes[key].server) return callback(null, null)
        if (!_note) {
          this.realtime.io.to(note.id).emit('info', {
            code: 404
          })
          logger.error('note not found: ', note.id)
        }

        if (err || !_note) {
          this.realtime.disconnectSocketOnNote(note)
          return callback(err, null)
        }

        note.updatetime = moment(_note.lastchangeAt).valueOf()
        this.realtime.emitCheck(note)
        return callback(null, null)
      })
    }, (err) => {
      if (err) return logger.error('updater error', err)
    })
  }
}

exports.UpdateDirtyNoteJob = UpdateDirtyNoteJob

'use strict'

const config = require('./config')
const logger = require('./logger')
const moment = require('moment')

class UpdateDirtyNoteJob {
  constructor (realtime) {
    this.realtime = realtime
  }

  start () {
    if (this.timer) return
    this.timer = setInterval(this.updateDirtyNotes.bind(this), 1000)
  }

  stop () {
    if (!this.timer) return
    clearInterval(this.timer)
    this.timer = undefined
  }

  updateDirtyNotes () {
    const notes = this.realtime.getNotePool()
    Object.keys(notes).forEach((key) => {
      const note = notes[key]
      this.updateDirtyNote(note)
        .catch((err) => {
          logger.error('updateDirtyNote: updater error', err)
        })
    })
  }

  async updateDirtyNote (note) {
    const notes = this.realtime.getNotePool()
    if (!note.server.isDirty) return

    if (config.debug) logger.info('updateDirtyNote: updater found dirty note: ' + note.id)
    note.server.isDirty = false

    try {
      const _note = await this.updateNoteAsync(note)
      // handle when note already been clean up
      if (!notes[note.id] || !notes[note.id].server) return

      if (!_note) {
        this.realtime.io.to(note.id).emit('info', {
          code: 404
        })
        logger.error('updateDirtyNote: note not found: ', note.id)
        this.realtime.disconnectSocketOnNote(note)
      }

      note.updatetime = moment(_note.lastchangeAt).valueOf()
      this.realtime.emitCheck(note)
    } catch (err) {
      logger.error('updateDirtyNote: note not found: ', note.id)
      this.realtime.io.to(note.id).emit('info', {
        code: 404
      })
      this.realtime.disconnectSocketOnNote(note)
      throw err
    }
  }

  updateNoteAsync (note) {
    return new Promise((resolve, reject) => {
      this.realtime.updateNote(note, (err, _note) => {
        if (err) {
          return reject(err)
        }
        return resolve(_note)
      })
    })
  }
}

exports.UpdateDirtyNoteJob = UpdateDirtyNoteJob

update dirty note job