# This file is part of bish-bosh. It is subject to the licence terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/raphaelcohn/bish-bosh/master/COPYRIGHT. No part of bish-bosh, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
# Copyright © 2014-2015 The developers of bish-bosh. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/raphaelcohn/bish-bosh/master/COPYRIGHT.


_bishbosh_connection_write_SUBSCRIBE_validateArguments()
{
	if [ $# -lt 2 ]; then
		core_exitError $core_commandLine_exitCode_CONFIG "The argument 'bishbosh_subscribe_topicQoSPairs' must contain at least one pair"
	fi
	
	if [ $(($#%2)) -ne 0 ]; then
		core_exitError $core_commandLine_exitCode_CONFIG "The argument 'bishbosh_subscribe_topicQoSPairs' must contain pairs"
	fi	
	
	local topicFilter
	local topicQoS
	local index=0
	local topicFilterFieldLength
	while [ $# -gt 0 ]
	do
		topicFilter="$1"
		bishbosh_connection_validate_topicFilter 'bishbosh_subscribe_topicQoSPairs' $index "$topicFilter"
		
		topicQoS=$2
		case "$topicQoS" in
			
			0|1|2)
				:
			;;
			
			*)
				core_exitError $core_commandLine_exitCode_CONFIG "The argument 'bishbosh_subscribe_topicQoSPairs' at pair index '$index' must contain QoS values between 0 to 2 (inclusive), not '$topicQoS'"
			;;
		esac
		
		topicFilterFieldLength=${#topicFilter}
		# 3 == 2 bytes length + 1 byte QoS
		remainingLength=$(( remainingLength + 3 + topicFilterFieldLength ))
		
		shift 2
		index=$((index+1))
	done
}

_bishbosh_connection_write_SUBSCRIBE_store()
{
	local topicFiltersPath="$ourPacketIdentifierFolderPath"/topic-filters
	
	local topicFilter
	local topicQoS
	local index=0
	local indexPath
	while [ $# -gt 0 ]
	do
		topicFilter="$1"
		topicQoS=$2
		
		# This rather odd looking syntax produces fixed-width numbers which sort easily in a glob-expression
		indexPath="$topicFiltersPath"/"$(printf '%09s' $index)"
		
		mkdir -m 0700 -p "$indexPath"
		printf '%s' $topicQoS >"$indexPath"/topic-qos
		printf '%s' "$topicFilter" >"$indexPath"/topic-filter
		
		shift 2
		index=$((index+1))
	done
}

core_usesIn bishbosh/connection write
_bishbosh_connection_write_SUBSCRIBE()
{
	local remainingLength=2
	_bishbosh_connection_write_SUBSCRIBE_validateArguments "$@"
	
	bishbosh_connection_packetIdentifier_useOneOfOurs subscribe _bishbosh_connection_write_SUBSCRIBE_store "$@"
	
	# 8 << 4 + 1 << 1 in octal
	printf '\202'
	bishbosh_connection_write_remainingLength $remainingLength
	bishbosh_connection_packetIdentifier_write

	local topicFilter
	local topicQoS
	while [ $# -gt 0 ]
	do
		topicFilter="$1"
		topicQoS=$2
		shift 2
		
		bishbosh_connection_write_twoByteLength ${#topicFilter}
		printf '%s' "$topicFilter"
		bishbosh_connection_write_byte $topicQoS
	done
	
	bishbosh_connection_ping_recordLastSentControlPacketAt
}

# requires packetIdentifier
bishbosh_connection_write_reSUBSCRIBE()
{
	local ourPacketIdentifierFolderPath
	bishbosh_connection_packetIdentifier_ourPacketIdentifierFolderPath
	
	local topicFiltersPath="$ourPacketIdentifierFolderPath"/topic-filters
	if [ ! -d "$topicFiltersPath" ]; then
		core_message WARN "There are no topic filters in '$topicFiltersPath'; data is corrupt"
		return 0
	fi
	
	local remainingLength=2

	local paddedIndex
	
	local topicFilterFieldLength
	pushd "$topicFiltersPath"
	
		set +f
		for paddedIndex in *
		do
			set -f
			if [ ! -e "$paddedIndex" ]; then
				core_message WARN "There are no padded indices in '$topicFiltersPath'; data is corrupt"
				return 0
			fi
			if [ ! -d "$paddedIndex" ]; then
				core_message WARN "What is '$topicFiltersPath'/'$paddedIndex' doing there?"
				continue
			fi
			
			topicFilterFieldLength=$(bishbosh_filesize_${bishbosh_filesizeAlgorithm} "$paddedIndex"/topic-filter)
			remainingLength=$(( remainingLength + 3 + topicFilterFieldLength ))
		done
		set -f
	
	popd
	
	# 8 << 4 + 1 << 1 in octal
	printf '\202'
	bishbosh_connection_write_remainingLength $remainingLength
	
	local bishbosh_connection_packetIdentifier_forWriting=$packetIdentifier
	bishbosh_connection_packetIdentifier_write
	
	pushd "$topicFiltersPath"

		set +f
		for paddedIndex in *
		do
			set -f
			topicFilterFieldLength=$(bishbosh_filesize_${bishbosh_filesizeAlgorithm} "$paddedIndex"/topic-filter)
			bishbosh_connection_write_file "$paddedIndex"/topic-filter $topicFilterFieldLength
			bishbosh_connection_write_byte $(<"$paddedIndex"/topic-qos)
		done
		set -f
		
	popd
	
	bishbosh_connection_ping_recordLastSentControlPacketAt
}

bishbosh_subscribe()
{
	_bishbosh_connection_write_SUBSCRIBE "$@"
}
