--[[
ģƣpublishط
ģ鹦ܣQoSΪ1publishط
          publishĺDUP_TIMEûյpubackԶططDUP_CNTΣûյpubackط׳MQTT_DUP_FAILϢȻñ
ģ޸ʱ䣺2017.02.24
]]

module(...,package.seeall)

--DUP_TIMEpublishĺDUP_TIMEжûյpuback
--DUP_CNTûյpubackĵpublishط
--tlistpublishĴ洢
local DUP_TIME,DUP_CNT,tlist = 10,3,{}
local slen = string.len

--[[
print
  ӡӿڣļедӡmqttdupǰ׺
  
ֵ
]]
local function print(...)
	_G.print("mqttdup",...)
end

--[[
timerfnc
  1ĶʱѯtlistеpublishǷʱҪط
  
ֵ
]]
local function timerfnc()
	print("timerfnc")
	for i=1,#tlist do
		print(i,tlist[i].tm)
		if tlist[i].tm > 0 then
			tlist[i].tm = tlist[i].tm-1
			if tlist[i].tm == 0 then
				sys.dispatch("MQTT_DUP_IND",tlist[i].sckidx,tlist[i].dat)
			end
		end
	end
end

--[[
timer
  ߹ر1Ķʱ
  
		start߹رգtruefalsenilر
ֵ
]]
local function timer(start)
	print("timer",start,#tlist)
	if start then
		if not sys.timer_is_active(timerfnc) then
			sys.timer_loop_start(timerfnc,1000)
		end
	else
		if #tlist == 0 then sys.timer_stop(timerfnc) end
	end
end

--[[
ins
  һpublishĵ洢
  
		sckidxsocket idx
		typԶ
		datpublish
		seqpublishк
		cbûص
		cbtagûصĵһ
ֵ
]]
function ins(sckidx,typ,dat,seq,cb,cbtag)
	print("ins",typ,(slen(dat or "") > 200) and "" or common.binstohexs(dat),seq or "nil" or common.binstohex(seq))
	table.insert(tlist,{sckidx=sckidx,typ=typ,dat=dat,seq=seq,cb=cb,cbtag=cbtag,cnt=DUP_CNT,tm=DUP_TIME})
	timer(true)
end

--[[
rmv
  Ӵ洢ɾһpublish
  
		sckidxsocket idx
		typԶ
		datpublish
		seqpublishк
ֵ
]]
function rmv(sckidx,typ,dat,seq)
	print("rmv",typ or getyp(seq),(slen(dat or "") > 200) and "" or common.binstohexs(dat),seq or "nil" or common.binstohex(seq))
	for i=1,#tlist do
		if (sckidx == tlist[i].sckidx) and (not typ or typ == tlist[i].typ) and (not dat or dat == tlist[i].dat) and (not seq or seq == tlist[i].seq) then
			table.remove(tlist,i)
			break
		end
	end
	timer()
end

--[[
rmvall
  Ӵ洢ɾpublish
  
		sckidxsocket idx
ֵ
]]
function rmvall(sckidx)
	tlist = {}
	for i=#tlist,1,-1 do
		if sckidx == tlist[i].sckidx then
			table.remove(tlist,i)
		end
	end
	timer()
end

--[[
rsm
  طһpublishĺĻص
  
		sckidxsocket idx
		spublish
ֵ
]]
function rsm(sckidx,s)
	for i=1,#tlist do
		if sckidx==tlist[i].sckidx and tlist[i].dat==s then
			tlist[i].cnt = tlist[i].cnt - 1
			if tlist[i].cnt == 0 then
				sys.dispatch("MQTT_DUP_FAIL",tlist[i].sckidx,tlist[i].typ,tlist[i].seq,tlist[i].cb,tlist[i].cbtag)
				rmv(tlist[i].sckidx,nil,s) 
				return 
			end
			tlist[i].tm = DUP_TIME			
			break
		end
	end
end

--[[
getyp
  кŲpublishûԶ
  
		sckidxsocket idx
		seqpublishк
ֵûԶ͡ûصûصĵһ
]]
function getyp(sckidx,seq)
	for i=1,#tlist do
		if seq and seq == tlist[i].seq and sckidx==tlist[i].sckidx then
			return tlist[i].typ,tlist[i].cb,tlist[i].cbtag
		end
	end
end
