# $Id: bkup_conferences.tcl 1440 2008-05-20 17:51:38Z sergei $
# Support for backup/restore of "roster bookmarks" to MUC rooms (XEP-0048, v1.0)
# Depends on: conferences.tcl, backup.tcl

namespace eval mucbackup {
    # Should probably go after the roster contacts, so we set prio to 70:
    hook::add serialize_roster_hook \
	[namespace current]::serialize_muc_bookmarks 70
    hook::add deserialize_roster_hook \
	[namespace current]::deserialize_muc_bookmarks 70
}

###############################################################################

proc mucbackup::serialize_muc_bookmarks {connid level varName} {
    upvar $level $varName subtags
    global NS

    foreach xmldata [::plugins::conferences::serialize_bookmarks $connid] {
	lappend subtags [jlib::wrapper:createtag privstorage \
	    -vars [list xmlns $NS(private)] \
	    -subtags [list $xmldata]]
    }
}

###############################################################################

proc mucbackup::deserialize_muc_bookmarks {connid data level varName} {
    global NS
    upvar $level $varName handlers

    set bookmarks [list]
    set bmgroups  [list]
    foreach item $data {
	jlib::wrapper:splitxml $item tag vars isempty cdata children
	if {![string equal $tag privstorage]} continue
	set xmlns [jlib::wrapper:getattr $vars xmlns]
	if {![string equal $xmlns $NS(private)]} {
	    return -code error "Bad roster element namespace \"$xmlns\":\
		must be \"$NS(private)\""
	}

	foreach storage $children {
	    jlib::wrapper:splitxml $storage ctag cvars cisempty ccdata cchildren
	    if {![string equal $ctag storage]} continue
	    set xmlns [jlib::wrapper:getattr $cvars xmlns]
	    switch -- $xmlns \
		$NS(bookmarks) {
		    set bookmarks [concat $bookmarks $cchildren]
		} \
		$NS(tkabber:groups) {
		    set bmgroups [concat $bmgroups $cchildren]
		}
	}
    }

    if {[llength $bookmarks] > 0 && [llength $bmgroups] > 0} {
	lappend handlers [list 70 [namespace code [list \
	    merge_muc_bookmarks $connid $bookmarks $bmgroups]]]
    }
}

###############################################################################

proc mucbackup::merge_muc_bookmarks {connid bookmarks bmgroups continuation} {
    variable updated 0

    foreach item $bookmarks {
	set added [::plugins::conferences::create_muc_bookmark \
		$connid $item -merge yes]
	set updated [expr {$updated || $added}]
    }

    foreach item $bmgroups {
	set added [::plugins::conferences::create_muc_bmgroup \
		$connid $item -merge yes]
	set updated [expr {$updated || $added}]
    }

    if {$updated} {
	::plugins::conferences::store_bookmarks $connid \
	    -command [namespace code [list process_merging_result $continuation]]
	::plugins::conferences::push_bookmarks_to_roster $connid
    } else {
	eval $continuation
    }
}

###############################################################################

proc mucbackup::process_merging_result {continuation result xmldata} {
    switch -- $result {
	OK {
	    eval $continuation
	}
	default {
	    # TODO check whether TIMEOUT should be processed separately
	    NonmodalMessageDlg [epath] \
		-aspect 50000 \
		-icon error \
		-title [::msgcat::mc "Error"] \
		-message [::msgcat::mc "Error restoring conference bookmarks: %s" \
		    [error_to_string $xmldata]]
	}
    }
}

# vim:ts=8:sw=4:sts=4:noet
