1package xmpp
2
3import (
4	"bytes"
5	"encoding/xml"
6	"fmt"
7	"time"
8
9	"github.com/coyim/coyim/xmpp/data"
10)
11
12const requestDelimiterXML = `
13<iq type='get' id='%x'>
14  <query xmlns='jabber:iq:private'>
15    <roster xmlns='roster:delimiter'/>
16  </query>
17</iq>
18`
19
20type rosterDelimiter struct {
21	XMLName   xml.Name `xml:"roster:delimiter roster"`
22	delimiter string   `xml:",chardata"`
23}
24
25type rosterQuery struct {
26	XMLName   xml.Name        `xml:"jabber:iq:private query"`
27	delimiter rosterDelimiter `xml:"roster:delimiter roster"`
28}
29
30// GetRosterDelimiter blocks and waits for the roster delimiter to be delivered
31func (c *conn) GetRosterDelimiter() (string, error) {
32	rep, _, err := c.RequestRosterDelimiter()
33	if err != nil {
34		return "", err
35	}
36
37	select {
38	case iqStanza := <-rep:
39		stanza, ok := iqStanza.Value.(*data.ClientIQ)
40		if ok {
41			var rst rosterQuery
42			if err := xml.NewDecoder(bytes.NewBuffer(stanza.Query)).Decode(&rst); err != nil || len(rst.delimiter.delimiter) == 0 {
43				return "", nil
44			}
45			return rst.delimiter.delimiter, nil
46		}
47	case <-time.After(5000 * time.Millisecond):
48	}
49
50	return "", nil
51}
52
53// RequestRosterDelimiter will request the roster delimiter
54func (c *conn) RequestRosterDelimiter() (<-chan data.Stanza, data.Cookie, error) {
55	cookie := c.getCookie()
56	if _, err := fmt.Fprintf(c.out, requestDelimiterXML, cookie); err != nil {
57		return nil, 0, err
58	}
59
60	return c.createInflight(cookie, "")
61}
62