package require tcltest 2
namespace import -force tcltest::*

loadFile [file join [file dirname [info script]] client.tcl]

loadTestedCommands

test message-1.0.0 {send message and receive echo (v4)} -setup {
    echoclient
} -body {
    mqtt create mq -protocol 4
    mq subscribe tcltest/set/# [list message]
    mq connect tcltest
    mq publish tcltest/echo/tcltest/set/done data
    dict getdef [varwait done 1000] topic ""
} -cleanup {
    mq destroy
} -result tcltest/set/done

test message-1.0.1 {send message and receive echo (v5)} -constraints MQTTV5 -setup {
    echoclient
} -body {
    mqtt create mq -protocol 5
    mq subscribe -properties {SubscriptionIdentifier 4442} tcltest/set/# [list message]
    mq connect tcltest
    mq publish tcltest/echo/tcltest/set/done data
    dict getdef [varwait done 1000] properties SubscriptionIdentifier ""
} -cleanup {
    mq destroy
} -result 4442

# Fails on mosquitto 2.0.12 (fixed by 7551a29)
test message-1.1.1 {will message (v5)} -constraints {MQTTV5 FIX7551A29} -setup {
    echoclient
} -body {
    mqtt create mq -protocol 5
    mq will -properties {PayloadFormatIndicator 1} tcltest/var/done will
    mq connect tcltest
    after 200 {mq disconnect 4}
    dict getdef [varwait done 1000] properties PayloadFormatIndicator ""
} -cleanup {
    mq destroy
} -result 1

test message-1.2.0 {send message with assured delivery (v4)} -body {
    mqtt create mq -protocol 4
    mq subscribe {$SYS/local/publication} [list sysmsg done]
    mq connect tcltest
    mq publish tcltest/publish/something data 2
    dict getdef [varwait done 1000] data topic ""
} -cleanup {
    mq destroy
} -result tcltest/publish/something

test message-1.2.1 {send message with assured delivery (v5)} -constraints MQTTV5 -body {
    mqtt create mq -protocol 5
    mq subscribe {$SYS/local/publication} [list sysmsg done]
    mq connect tcltest
    mq publish tcltest/publish/something data 2
    dict getdef [varwait done 1000] data topic ""
} -cleanup {
    mq destroy
} -result tcltest/publish/something

test message-1.3.0 {subscribe and unsubscribe (v4)} -body {
    mqtt create mq -protocol 4
    mq subscribe {$SYS/local/subscription} [list sysmsg done]
    mq subscribe tcltest/set/# [list message]
    mq connect tcltest
    varwait done 1000
    mq unsubscribe tcltest/set/# [list message]
    dict getdef [varwait done 1000] data ""
} -cleanup {
    mq destroy
} -result {tcltest/set/# {}}

test message-1.3.1 {subscribe and unsubscribe (v5)} -constraints MQTTV5 -body {
    mqtt create mq -protocol 5
    mq subscribe {$SYS/local/subscription} [list sysmsg done]
    mq subscribe -properties {SubscriptionIdentifier 4442} tcltest/set/# [list message]
    mq connect tcltest
    varwait done 1000
    mq unsubscribe tcltest/set/# [list message]
    dict getdef [varwait done 1000] data ""
} -cleanup {
    mq destroy
} -result {tcltest/set/# {}}

test message-1.4.0 {unsubscribe before subscribe (v4)} -body {
    mqtt create mq -protocol 4
    mq connect tcltest
    mq unsubscribe tcltest/set/#
    mq subscribe tcltest/set/# [list message]
    mq publish tcltest/set/done data
    dict get [varwait done 1000] result
} -cleanup {
    mq destroy
} -result message

test message-1.4.1 {unsubscribe before subscribe (v5)} -constraints MQTTV5 -body {
    mqtt create mq -protocol 5
    mq connect tcltest
    mq unsubscribe tcltest/set/#
    mq subscribe tcltest/set/# [list message]
    mq publish tcltest/set/done data
    dict get [varwait done 1000] result
} -cleanup {
    mq destroy
} -result message

test message-1.5.0 {modify subscription callback (v4)} -body {
    mqtt create mq -protocol 4
    mq subscribe {$SYS/local/subscription} [list sysmsg done]
    mq subscribe tcltest/set/# [list mistake]
    mq subscribe tcltest/set/# [list message] -1
    mq connect tcltest
    dict getdef [varwait done 1000] data ""
} -cleanup {
    mq destroy
} -result {tcltest/set/# 2}

test message-1.5.1 {modify subscription callback (v5)} -constraints MQTTV5 -body {
    mqtt create mq -protocol 5
    mq subscribe {$SYS/local/subscription} [list sysmsg done]
    mq subscribe tcltest/set/# [list mistake]
    mq subscribe tcltest/set/# [list message] -1
    mq connect tcltest
    dict getdef [varwait done 1000] data ""
} -cleanup {
    mq destroy
} -result {tcltest/set/# 2}

test message-1.6.1 {shared subscription (v5)} -constraints MQTTV5 -setup {
    echoclient
} -body {
    mqtt create mq -protocol 5
    mq subscribe {$share/test/tcltest/set/#} [list message]
    mq connect tcltest
    mq publish tcltest/echo/tcltest/set/done data
    dict getdef [varwait done 1000] topic ""
} -cleanup {
    mq destroy
} -result tcltest/set/done

test message-2.0 {in-flight messages qos 1 (v5)} -constraints FIX4AE8971 -setup {
    echoclient
} -body {
    mqtt create mq -protocol 5
    mq connect -properties {ReceiveMaximum 50} tcltest
    mq publish tcltest/var/done1 data1 1
    mq publish tcltest/var/done2 data2 1
    mq publish tcltest/var/done3 data3 1
    mq publish tcltest/var/done4 data4 1
    mq publish tcltest/var/done5 data5 1
    mq publish tcltest/var/done6 data6 1
    mq publish tcltest/var/done7 data7 1
    mq publish tcltest/var/done8 data8 1
    set done 0
    incr done [expr {[dict get [varwait done1 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done2 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done3 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done4 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done5 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done6 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done7 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done8 1000] result] eq "message"}]
} -cleanup {
    mq destroy
} -result 8

test message-2.1 {in-flight messages qos 2 (v5)} -constraints FIX4AE8971 -setup {
    echoclient
} -body {
    mqtt create mq -protocol 5
    mq connect -properties {ReceiveMaximum 50} tcltest
    mq publish tcltest/var/done1 data1 2
    mq publish tcltest/var/done2 data2 2
    mq publish tcltest/var/done3 data3 2
    mq publish tcltest/var/done4 data4 2
    mq publish tcltest/var/done5 data5 2
    mq publish tcltest/var/done6 data6 2
    mq publish tcltest/var/done7 data7 2
    mq publish tcltest/var/done8 data8 2
    set done 0
    incr done [expr {[dict get [varwait done1 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done2 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done3 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done4 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done5 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done6 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done7 1000] result] eq "message"}]
    incr done [expr {[dict get [varwait done8 1000] result] eq "message"}]
} -cleanup {
    mq destroy
} -result 8

# cleanup
kill
cleanupTests
