# $Id: ibb.tcl 1209 2007-08-31 11:52:26Z sergei $

namespace eval ::ibb {}

proc ::ibb::connect {connid jid key} {
    variable connection

    set_status [::msgcat::mc "Opening IBB connection"]

    jlib::send_iq set \
	[jlib::wrapper:createtag query \
	     -vars {xmlns jabber:iq:ibb} \
	     -subtags [list [jlib::wrapper:createtag comment \
				 -subtags [list [jlib::wrapper:createtag key \
						     -chdata $key]]]]] \
	-to $jid -command [list ibb::recv_connect_response $connid $jid $key] \
	-connection $connid
	 
    vwait [namespace current]::connection(status,$key)
}

proc ::ibb::recv_connect_response {connid jid key res child} {
    variable connection

    if {$res != "OK"} {
	# TODO
	set connection(status,$key) 0
	return
    }

    jlib::wrapper:splitxml $child tag vars isempty chdata children

    if {$tag == "query"} {
	foreach item $children {
	    jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1
	    if {$tag1 == "streamid"} {
		set streamid $chdata1
		debugmsg jidlink "STREAMID: $streamid"
	    }
	}

	if {[info exists streamid]} {
	    variable stream_key
	    variable key_stream

	    set stream_key($streamid) $key
	    set key_stream($key) $streamid

	    set connection(connid,$key) $connid
	    set connection(jid,$key) $jid
	    set connection(status,$key) 1

	} else {
	    # TODO
	}
    } else {
	# TODO
    }
    set connection(status,$key) 0
}

package require base64

proc ::ibb::send_data {key data} {
    variable connection
    variable key_stream

    debugmsg jidlink [array get stream_key]

    jlib::send_iq set \
	[jlib::wrapper:createtag query \
	     -vars {xmlns jabber:iq:inband} \
	     -subtags [list [jlib::wrapper:createtag streamid \
				 -chdata $key_stream($key)] \
			   [jlib::wrapper:createtag data \
				-chdata [base64::encode $data]]]] \
	-to $connection(jid,$key) \
	-command [list ibb::send_data_ack $key] \
	-connection $connection(connid,$key)

    vwait [namespace current]::connection(ack,$key)

    return $connection(ack,$key)
}

proc ::ibb::send_data_ack {key res child} {
    variable connection
    if {$res != "OK"} {
	# TODO
	set connection(ack,$key) 0
	return
    }
    set connection(ack,$key) 1
}

proc ::ibb::close {key} {
    variable connection
    variable key_stream

    jlib::send_iq set \
	[jlib::wrapper:createtag query \
	     -vars {xmlns jabber:iq:inband} \
	     -subtags [list [jlib::wrapper:createtag streamid \
				 -chdata $key_stream($key)] \
			   [jlib::wrapper:createtag close]]] \
	-to $connection(jid,$key) \
	-connection $connection(connid,$key)

}

proc ::ibb::iq_set_handler {connid from lang child} {
    jlib::wrapper:splitxml $child tag vars isempty chdata children

    if {$tag == "query"} {
	foreach item $children {
	    jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1
	    if {$tag1 == "comment"} {
		foreach item1 $children1 {
		    jlib::wrapper:splitxml $item1 tag2 vars2 isempty2 \
			chdata2 children2
		    if {$tag2 == "key"} {
			set key $chdata2
			debugmsg jidlink "KEY: $key"
		    }
		}
	    }
	}

	if {[info exists key]} {
	    variable stream_key
	    variable key_stream

	    set streamid [rand 1000000000]
	    set stream_key($streamid) $key
	    set key_stream($key) $streamid

	    set res [jlib::wrapper:createtag query \
			 -vars {xmlns jabber:iq:ibb} \
			 -subtags [list [jlib::wrapper:createtag streamid \
					     -chdata $streamid]]]
	    return [list result $res]
	} else {
	    # TODO
	}
    } else {
	# TODO
    }
}

iq::register_handler set query jabber:iq:ibb ibb::iq_set_handler

proc ::ibb::iq_inband_set_handler {connid from lang child} {
    variable stream_key

    jlib::wrapper:splitxml $child tag vars isempty chdata children

    if {$tag == "query"} {
	foreach item $children {
	    jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1
	    switch -- $tag1 {
		streamid {
		    set streamid $chdata1
		}
		data {
		    set data $chdata1
		}
		close {
		    set close 1
		}
	    }
	}

	if {[info exists streamid] && [info exists stream_key($streamid)]} {
	    if {[info exists data]} {
		if {[catch {set decoded [base64::decode $data]}]} {
		    # TODO
		    debugmsg jidlink "IBB: WRONG DATA"
		} else {
		    debugmsg jidlink "IBB: RECV DATA [list $data]"
		    jidlink::recv_data $stream_key($streamid) $decoded
		}
		
	    }
	    
	    if {[info exists close]} {
		jidlink::closed $stream_key($streamid)
	    }

	    return [list result ""]
	} else {
	    # TODO
	}
    } else {
	# TODO
    }
}

iq::register_handler set query jabber:iq:inband ibb::iq_inband_set_handler

jidlink::register_transport inband-bytestream inband-bytestream 75 \
    ibb::connect ibb::send_data ibb::close

