model: add Conversation, Account

Change-Id: Ia0717957d9b7489dd2b299ad9f8696e25b662ec7
diff --git a/JamiDaemon.js b/JamiDaemon.js
index e85ea9b..59d6b2b 100755
--- a/JamiDaemon.js
+++ b/JamiDaemon.js
@@ -18,6 +18,7 @@
  *  along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 const Account = require('./model/Account')
+const Conversation = require('./model/Conversation')
 
 "use strict";
 class JamiDaemon {
@@ -36,9 +37,9 @@
                         }
                     }
                     newAccounts.push(new Account(accountId,
-                        this.mapToJs(this.dring.getAccountDetails(accountId))
-                        //this.mapToJs(this.dring.getVolatileDetails(accountId)),
-                        ))
+                        this.mapToJs(this.dring.getAccountDetails(accountId)),
+                        this.mapToJs(this.dring.getVolatileAccountDetails(accountId))
+                    ))
                 })
                 this.accounts = newAccounts
             },
@@ -97,7 +98,75 @@
                 }
             },
             "RegisteredNameFound": (accountId, state, address, name) => {
-                console.log("RegistrationStateChanged: " + accountId + " " + state + " " + address + " " + name)
+                console.log(`RegisteredNameFound: ${accountId} ${state} ${address} ${name}`)
+            },
+            "conversationReady": (accountId, conversationId) => {
+                console.log(`conversationReady: ${accountId} ${conversationId}`)
+                const account = this.getAccount(accountId)
+                if (!account) {
+                    console.log(`Unknown account ${accountId}`)
+                    return
+                }
+                let conversation = account.getConversation(conversationId)
+                if (!conversation) {
+                    const members = this.dring.getConversationMembers(accountId, conversationId)
+                    console.log(members)
+                    conversation = new Conversation(conversationId, members)
+                    account.addConversation(conversation)
+                }
+            },
+            "conversationRemoved": (accountId, conversationId) => {
+                console.log(`conversationRemoved: ${accountId} ${conversationId}`)
+                const account = this.getAccount(accountId)
+                if (!account) {
+                    console.log(`Unknown account ${accountId}`)
+                    return
+                }
+                account.removeConversation(conversationId)
+            },
+            "conversationLoaded": (accountId, conversationId) => {
+                console.log(`conversationLoaded: ${accountId} ${conversationId}`)
+                const account = this.getAccount(accountId)
+                if (!account) {
+                    console.log(`Unknown account ${accountId}`)
+                    return
+                }
+            },
+            "messageReceived": (accountId, conversationId, message) => {
+                console.log(`messageReceived: ${accountId} ${conversationId}`)
+                const account = this.getAccount(accountId)
+                if (!account) {
+                    console.log(`Unknown account ${accountId}`)
+                    return
+                }
+                const conversation = account.getConversation(conversationId)
+                if (!conversation) {
+                    conversation.addMessage(message)
+                }
+            },
+            "conversationRequestReceived": (accountId, conversationId, request) => {
+                console.log(`conversationRequestReceived: ${accountId} ${conversationId}`)
+                const account = this.getAccount(accountId)
+                if (!account) {
+                    console.log(`Unknown account ${accountId}`)
+                    return
+                }
+            },
+            "conversationMemberEvent": (accountId, conversationId, member, event) => {
+                console.log(`conversationMemberEvent: ${accountId} ${conversationId}`)
+                const account = this.getAccount(accountId)
+                if (!account) {
+                    console.log(`Unknown account ${accountId}`)
+                    return
+                }
+            },
+            "onConversationError": (accountId, conversationId, code, what) => {
+                console.log(`onConversationError: ${accountId} ${conversationId}`)
+                const account = this.getAccount(accountId)
+                if (!account) {
+                    console.log(`Unknown account ${accountId}`)
+                    return
+                }
             }
         })
         this.stringVectToArr(this.dring.getAccountList()).forEach(accountId => {
@@ -147,7 +216,7 @@
 // private
 
     boolToStr(bool) {
-        return bool ? "TRUE" : "FALSE";
+        return bool ? "true" : "false";
     }
 
     accountDetailsToNative(account) {
diff --git a/jaas-client/src/components/AccountPreferences.js b/jaas-client/src/components/AccountPreferences.js
index f486dd9..5b6ae28 100644
--- a/jaas-client/src/components/AccountPreferences.js
+++ b/jaas-client/src/components/AccountPreferences.js
@@ -21,7 +21,7 @@
     const isJamiAccount = account.getType() === Account.TYPE_JAMI
     return (
       <React.Fragment>
-        <Typography variant="h2" component="h2">Jami account</Typography>
+        <Typography variant="h2" component="h2">{isJamiAccount ? "Jami account" : "SIP account"}</Typography>
 
         {isJamiAccount &&
           <JamiIdCard account={account} />}
diff --git a/model/Account.js b/model/Account.js
index 3141176..6b43f1c 100644
--- a/model/Account.js
+++ b/model/Account.js
@@ -1,8 +1,13 @@
+const Contact = require('./Contact')
+
 class Account {
     constructor(id, details, volatileDetails) {
         this.id = id
         this.details = details
         this.volatileDetails = volatileDetails
+        this.contactCache = {}
+        this.contacts = {}
+        this.conversations = {}
     }
 
     static from(object) {
@@ -14,6 +19,14 @@
         this.volatileDetails = data.volatileDetails
     }
 
+    getObject() {
+        return {
+            id: this.id,
+            details: this.details,
+            volatileDetails: this.volatileDetails
+        }
+    }
+
     getId() { return this.id }
 
     getType() { return this.details["Account.type"] }
@@ -23,15 +36,8 @@
     getRegisteredName() { return this.volatileDetails["Account.registeredName"] }
 
     isRendezVous() { return this.details["Account.rendezVous"] === Account.BOOL_TRUE }
-    isPublicIn() { return this.details["DHT.PublicInCalls"] === Account.BOOL_TRUE }
 
-    getObject() {
-        return {
-            id: this.id,
-            details: this.details,
-            volatileDetails: this.volatileDetails
-        }
-    }
+    isPublicIn() { return this.details["DHT.PublicInCalls"] === Account.BOOL_TRUE }
 
     getSummary() {
         return this.getObject()
@@ -44,6 +50,35 @@
     getDisplayUri() {
         return this.getRegisteredName() || this.getUri()
     }
+
+    getConversationIds() {
+        return Object.keys(this.conversations)
+    }
+
+    getConversation(conversationId) {
+        return this.conversations[conversationId]
+    }
+
+    addConversation(conversation) {
+        this.conversations[conversation.getId()] = conversation
+    }
+
+    removeConversation(conversationId) {
+        delete this.conversations[conversationId]
+    }
+
+    getContactFromCache(uri) {
+        let contact = this.contactCache[uri]
+        if (!contact) {
+            contact = new Contact(uri)
+            this.contactCache[uri] = contact
+        }
+        return contact
+    }
+
+    getContacts() {
+        return this.contacts
+    }
 }
 
 Account.TYPE_JAMI = "RING"
@@ -52,4 +87,4 @@
 Account.BOOL_TRUE = "true"
 Account.BOOL_FALSE = "false"
 
-module.exports = Account;
+module.exports = Account
diff --git a/model/Contact.js b/model/Contact.js
new file mode 100644
index 0000000..b21ddcd
--- /dev/null
+++ b/model/Contact.js
@@ -0,0 +1,27 @@
+class Contact {
+    constructor(uri) {
+        this.uri = uri
+        this.displayName = undefined
+        this.registeredName = undefined
+    }
+
+    static from(object) {
+        return new Contact(object.uri)
+    }
+
+    getUri() { return this.uri }
+
+    getRegisteredName() { this.registeredName }
+
+    getDisplayName() {
+        return this.displayName || this.getRegisteredName() || this.getUri()
+    }
+
+    getObject() {
+        return {
+            uri: this.uri
+        }
+    }
+}
+
+module.exports = Contact;
diff --git a/routes/jami.js b/routes/jami.js
index 90b9422..9ba97a7 100644
--- a/routes/jami.js
+++ b/routes/jami.js
@@ -1,4 +1,4 @@
-const express = require('express');
+const express = require('express')
 
 class JamiRestApi {
     constructor(jami) {
@@ -6,38 +6,54 @@
     }
 
     getRouter() {
-        const router = express.Router({mergeParams: true});
+        const router = express.Router({mergeParams: true})
 
         // Accounts
         router.get(['/accounts'], (req, res, next) => {
-            console.log("Request account list")
+            console.log("Get account list")
             res.json(this.jami.getAccountList().map(account => account.getSummary()))
-        });
+        })
 
         router.get(['/accounts/:accountId'], (req, res, next) => {
-            console.log(`Request account ${req.params.accountId}`)
-            const account = this.jami.getAccount(req.params.accountId);
+            console.log(`Get account ${req.params.accountId}`)
+            const account = this.jami.getAccount(req.params.accountId)
             if (account)
                 res.json(account.getObject())
             else
                 res.sendStatus(404)
-        });
+        })
+
+        // Contacts
+        router.get(['/accounts/:accountId/contacts'], (req, res, next) => {
+            console.log(`Get account ${req.params.accountId}`)
+            const account = this.jami.getAccount(req.params.accountId)
+            if (account)
+                res.json(account.getContacts())
+            else
+                res.sendStatus(404)
+        })
 
         // Conversations
-        const conversationRouter = express.Router({mergeParams: true});
+        const conversationRouter = express.Router({mergeParams: true})
         conversationRouter.get('/', (req, res, next) => {
-            console.log(`Request conversations for account ${req.params.accountId}`);
-            res.json([]);
+            console.log(`Get conversations for account ${req.params.accountId}`)
+            const account = this.jami.getAccount(req.params.accountId)
+            if (!account)
+                res.sendStatus(404)
+            res.json(account.getConversationIds())
         })
 
         conversationRouter.get('/:conversationId', (req, res, next) => {
-            console.log(`Request conversation ${req.params.conversationId} for account ${req.params.accountId}`);
-            res.json({});
+            console.log(`Get conversation ${req.params.conversationId} for account ${req.params.accountId}`)
+            const account = this.jami.getAccount(req.params.accountId)
+            if (!account)
+                res.sendStatus(404)
+            res.json(account.getConversation(req.params.conversationId))
         })
 
-        router.use('/accounts/:accountId/conversations', conversationRouter);
-        return router;
+        router.use('/accounts/:accountId/conversations', conversationRouter)
+        return router
     }
 }
 
-module.exports = JamiRestApi;
+module.exports = JamiRestApi