import eventToPromise from 'event-to-promise'
import XmppClient from 'node-xmpp-client'

// ===================================================================

export const configurationSchema = {
  type: 'object',

  properties: {
    transport: {
      type: 'object',

      properties: {
        host: {
          type: 'string',
          description: 'host where the XMPP server is located'
        },
        port: {
          type: 'integer',
          description: 'port of the XMPP server (default to 5222)',
          default: 5222
        },
        jid: {
          type: 'string',
          title: 'user',
          description: 'Xmpp address to use to authenticate'
        },
        password: {
          type: 'string',
          description: 'password to use to authenticate'
        }
      },

      additionalProperties: false,
      required: ['jid', 'password']
    }
  },

  additionalProperties: false,
  required: ['transport']
}

// ===================================================================

class TransportXmppPlugin {
  constructor (xo) {
    this._set = ::xo.defineProperty
    this._unset = null

    // Defined in configure().
    this._client = null
  }

  async configure ({ transport: conf }) {
    conf.reconnect = true
    this._client = new XmppClient(conf)
    this._client.on('error', () => {})

    return eventToPromise(this._client.connection.socket, 'data')
      .then(() => eventToPromise(this._client, 'online'))
  }

  load () {
    this._unset = this._set('sendToXmppClient', this._sendToXmppClient)
  }

  unload () {
    this._unset()
  }

  _sendToXmppClient ({to, message}) {
    const stanza = new XmppClient.Stanza('message', { to: to, type: 'chat' })
          .c('body').t(message)
    this._client.send(stanza)
  }
}

// ===================================================================

export default ({ xo }) => new TransportXmppPlugin(xo)

@@ -230,72 +230,8 @@
 : %7B%0A
-    transport: %7B%0A      type: 'object',%0A%0A      properties: %7B%0A    
     
@@ -234,28 +234,24 @@
     host: %7B%0A
-    
       type: 
@@ -258,36 +258,32 @@
 'string',%0A      
-    
 description: 'ho
@@ -319,20 +319,16 @@
 ocated'%0A
-    
     %7D,%0A 
@@ -330,20 +330,16 @@
  %7D,%0A    
-    
 port: %7B%0A
@@ -340,28 +340,24 @@
 rt: %7B%0A      
-    
 type: 'integ
@@ -357,28 +357,24 @@
  'integer',%0A
-    
       descri
@@ -431,20 +431,16 @@
 ,%0A      
-    
 default:
@@ -445,20 +445,16 @@
 t: 5222%0A
-    
     %7D,%0A 
@@ -460,23 +460,15 @@
     
-    
 jid: %7B%0A
-    
     
@@ -491,20 +491,16 @@
 ,%0A      
-    
 title: '
@@ -504,36 +504,32 @@
 : 'user',%0A      
-    
 description: 'Xm
@@ -567,27 +567,19 @@
 te'%0A    
-    %7D,%0A    
+%7D,%0A
     pass
@@ -586,20 +586,16 @@
 word: %7B%0A
-    
       ty
@@ -614,20 +614,16 @@
 ,%0A      
-    
 descript
@@ -665,99 +665,8 @@
 te'%0A
-        %7D%0A      %7D,%0A%0A      additionalProperties: false,%0A      required: %5B'jid', 'password'%5D%0A
     
@@ -718,25 +718,31 @@
 ired: %5B'
-transport
+jid', 'password
 '%5D%0A%7D%0A%0A//
@@ -856,24 +856,78 @@
 ctor (xo) %7B%0A
+    this._sendToXmppClient = ::this._sendToXmppClient%0A
     this._se
@@ -1005,16 +1005,65 @@
 gure().%0A
+    this._conf = null%0A%0A    // Defined in load().%0A
     this
@@ -1089,14 +1089,8 @@
 %0A%0A  
-async 
 conf
@@ -1100,35 +1100,48 @@
 re (
-%7B transport: conf %7D) %7B%0A    
+conf) %7B%0A    this._conf = conf%0A    this._
 conf
@@ -1158,16 +1158,39 @@
  = true%0A
+  %7D%0A%0A  async load () %7B%0A
     this
@@ -1215,16 +1215,22 @@
 pClient(
+this._
 conf)%0A  
@@ -1275,14 +1275,13 @@
     
-return
+await
  eve
@@ -1340,21 +1340,13 @@
     
-  .then(() =%3E
+await
  eve
@@ -1384,26 +1384,9 @@
 ne')
-)%0A  %7D%0A%0A  load () %7B
+%0A
 %0A   
@@ -1491,16 +1491,39 @@
 unset()%0A
+    this._client.end()%0A
   %7D%0A%0A  _

Make the client in load.