text: const EventEmitter = require('events')
  const ObservableStore = require('obs-store')
  const ethUtil = require('ethereumjs-util')
  const createId = require('./random-id')
  
  
  module.exports = class MessageManager extends EventEmitter {
    constructor (opts) {
      super()
      this.memStore = new ObservableStore({
        unapprovedMsgs: {},
        unapprovedMsgCount: 0,
      })
      this.messages = []
    }
  
    get unapprovedMsgCount () {
      return Object.keys(this.getUnapprovedMsgs()).length
    }
  
    getUnapprovedMsgs () {
      return this.messages.filter(msg => msg.status === 'unapproved')
      .reduce((result, msg) => { result[msg.id] = msg; return result }, {})
    }
  
    addUnapprovedMessage (msgParams) {
      msgParams.data = normalizeMsgData(msgParams.data)
      // create txData obj with parameters and meta data
      var time = (new Date()).getTime()
      var msgId = createId()
      var msgData = {
        id: msgId,
        msgParams: msgParams,
        time: time,
        status: 'unapproved',
        type: 'eth_sign',
      }
      this.addMsg(msgData)
  
      // signal update
      this.emit('update')
      return msgId
    }
  
    addMsg (msg) {
      this.messages.push(msg)
      this._saveMsgList()
    }
  
    getMsg (msgId) {
      return this.messages.find(msg => msg.id === msgId)
    }
  
    approveMessage (msgParams) {
      this.setMsgStatusApproved(msgParams.metamaskId)
      return this.prepMsgForSigning(msgParams)
    }
  
    setMsgStatusApproved (msgId) {
      this._setMsgStatus(msgId, 'approved')
    }
  
    setMsgStatusSigned (msgId, rawSig) {
      const msg = this.getMsg(msgId)
      msg.rawSig = rawSig
      this._updateMsg(msg)
      this._setMsgStatus(msgId, 'signed')
    }
  
    prepMsgForSigning (msgParams) {
      delete msgParams.metamaskId
      return Promise.resolve(msgParams)
    }
  
    rejectMsg (msgId) {
      this._setMsgStatus(msgId, 'rejected')
    }
  
    //
    // PRIVATE METHODS
    //
  
    _setMsgStatus (msgId, status) {
      const msg = this.getMsg(msgId)
      if (!msg) throw new Error('MessageManager - Message not found for id: "${msgId}".')
      msg.status = status
      this._updateMsg(msg)
      this.emit(`${msgId}:${status}`, msg)
      if (status === 'rejected' || status === 'signed') {
        this.emit(`${msgId}:finished`, msg)
      }
    }
  
    _updateMsg (msg) {
      const index = this.messages.findIndex((message) => message.id === msg.id)
      if (index !== -1) {
        this.messages[index] = msg
      }
      this._saveMsgList()
    }
  
    _saveMsgList () {
      const unapprovedMsgs = this.getUnapprovedMsgs()
      const unapprovedMsgCount = Object.keys(unapprovedMsgs).length
      this.memStore.updateState({ unapprovedMsgs, unapprovedMsgCount })
      this.emit('updateBadge')
    }
  
  }
  
  function normalizeMsgData (data) {
    if (data.slice(0, 2) === '0x') {
      // data is already hex
      return data
    } else {
      // data is unicode, convert to hex
      return ethUtil.bufferToHex(new Buffer(data, 'utf8'))
    }
  }
  