<commit_before>xmpp = require('node-xmpp')
NS = require('./ns')
forms = require('./forms')
uuid = require('node-uuid')

##
# All notifications are per-node, so listeners can be fetched once
#
# TODO: enforce MAX_STANZA_LIMIT
class Notification
    constructor: (@opts) ->

    toStanza: (fromJid, toJid) ->
        message = new xmpp.Element('message',
                type: 'headline'
                from: fromJid
                to: toJid
            )

        if @opts.replay
            # For the MAM case the stanza is packaged up into
            # <forwarded/>
            message.c('result',
                        xmlns: NS.MAM
                        queryid: @opts.queryId if @opts.queryId?
                        id: uuid()
                    ).up().
                c('forwarded', xmlns: NS.FORWARD).
                c('message',
                        type: 'headline'
                        from: fromJid
                        to: toJid
                    )
        else
            message

class EventNotification extends Notification
    toStanza: (fromJid, toJid) ->
        eventEl = super.c('event', xmlns: NS.PUBSUB_EVENT)
        for update in @opts
            switch update.type
                when 'items'
                    itemsEl = eventEl.
                        c('items', node: update.node)
                    if update.items? then for item in update.items
                        itemsEl.c('item', id: item.id).
                            cnode(item.el)
                    if update.retract? then for item in update.retract
                        itemsEl.c('retract', id: item.id)
                        itemsEl.c('item', id: item.id).
                            cnode(item.el)
                when 'subscription'
                    eventEl.
                        c('subscription',
                            jid: update.user
                            node: update.node
                            subscription: update.subscription
                        )
                when 'affiliation'
                    eventEl.
                        c('affiliation',
                            jid: update.user
                            node: update.node
                            affiliation: update.affiliation
                        )
                when 'config'
                    eventEl.
                        c('configuration',
                            node: update.node
                        ).cnode(forms.configToForm(update.config, 'result', NS.PUBSUB_NODE_CONFIG).toXml())
        eventEl

##
# <message to='<EMAIL>' from='pubsub.shakespeare.lit' id='approve1'>
#   <x xmlns='jabber:x:data' type='form'>
#     <title>PubSub subscriber request</title>
#     <instructions>
#       To approve this entity&apos;s subscription request,
#       click the OK button. To deny the request, click the
#       cancel button.
#     </instructions><commit_msg>Make affiliations notifications PubSub-compliant<commit_after>xmpp = require('node-xmpp')
NS = require('./ns')
forms = require('./forms')
uuid = require('node-uuid')

##
# All notifications are per-node, so listeners can be fetched once
#
# TODO: enforce MAX_STANZA_LIMIT
class Notification
    constructor: (@opts) ->

    toStanza: (fromJid, toJid) ->
        message = new xmpp.Element('message',
                type: 'headline'
                from: fromJid
                to: toJid
            )

        if @opts.replay
            # For the MAM case the stanza is packaged up into
            # <forwarded/>
            message.c('result',
                        xmlns: NS.MAM
                        queryid: @opts.queryId if @opts.queryId?
                        id: uuid()
                    ).up().
                c('forwarded', xmlns: NS.FORWARD).
                c('message',
                        type: 'headline'
                        from: fromJid
                        to: toJid
                    )
        else
            message

class EventNotification extends Notification
    toStanza: (fromJid, toJid) ->
        eventEl = super.c('event', xmlns: NS.PUBSUB_EVENT)
        affEls = {}
        for update in @opts
            switch update.type
                when 'items'
                    itemsEl = eventEl.
                        c('items', node: update.node)
                    if update.items? then for item in update.items
                        itemsEl.c('item', id: item.id).
                            cnode(item.el)
                    if update.retract? then for item in update.retract
                        itemsEl.c('retract', id: item.id)
                        itemsEl.c('item', id: item.id).
                            cnode(item.el)
                when 'subscription'
                    eventEl.
                        c('subscription',
                            jid: update.user
                            node: update.node
                            subscription: update.subscription
                        )
                when 'affiliation'
                    if update.node of affEls
                        affEl = affEls[update.node]
                    else
                        affEl = eventEl.c('affiliations', node: update.node)
                        affEls[update.node] = affEl
                    affEl.c('affiliation',
                        jid: update.user
                        affiliation: update.affiliation
                    )
                when 'config'
                    eventEl.
                        c('configuration',
                            node: update.node
                        ).cnode(forms.configToForm(update.config, 'result', NS.PUBSUB_NODE_CONFIG).toXml())
        eventEl

##
# <message to='<EMAIL>' from='pubsub.shakespeare.lit' id='approve1'>
#   <x xmlns='jabber:x:data' type='form'>
#     <title>PubSub subscriber request</title>
#     <instructions>
#       To approve this entity&apos;s subscription request,
#       click the OK button. To deny the request, click the
#       cancel button.
#     </instructions>
{'fraction_non_alphanumeric': 0.09442342490541207, 'fraction_numerical': 0.0003290014805066623, 'mean_word_length': 1.1415991546319126, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1349908', 'n_tokens_mistral': 1584, 'n_tokens_neox': 1494, 'n_words': 375}