--ģ,
require"aliyuniotssl"
require"https"
module(...,package.seeall)

--gVersion̼汾ַûûеñļsetVerӿãĬΪ_G.PROJECT.."_".._G.VERSION.."_"..sys.getcorever()
--gPathiotվõ¹̼ļغģеı·ûûеñļsetNameӿãĬΪ/luazip/update.bin
--gCb¹̼سɹҪִеĻص
local gVersion,gPath,gCb = _G.PROJECT.."_".._G.VERSION.."_"..sys.getcorever(),"/luazip/update.bin"

--productKeyƷʶ
--deviceName豸
local productKey,deviceName

--verRpted汾ǷѾϱ
local verRpted

--httpClient¹̼http client
--httpUrlgetеurlֶ
local httpClient,httpHost,httpUrl
--ƺ̨µ¹̼MD5ֵ
local gFileMD5,gFileSize,gFilePath

--lastStepһϱ¹̼Ľ
local lastStep


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

--[[
verRptCb
  ϱ̼汾Ÿƶ˺յPUBACKʱĻص
  
		tag˴
		resulttrueʾϱɹfalsenilʾʧ
ֵ
]]
local function verRptCb(tag,result)
	print("verRptCb",result)
	verRpted = result
	if not result then sys.timer_start(verRpt,20000) end
end

--[[
verRpt
  ϱ̼汾Ÿƶ
  
ֵ
]]
function verRpt()
	print("verRpt",gVersion)
	aliyuniotssl.publish("/ota/device/inform/"..productKey.."/"..deviceName,"{\"id\":1,\"params\":{\"version\":\""..gVersion.."\"}}",1,verRptCb)
end

--[[
connectedCb
  MQTT CONNECTɹص
  
		keyProductKey
		name豸
ֵ
]]
function connectedCb(key,name)
	print("connectedCb",verRpted)
	productKey,deviceName = key,name
	--
	aliyuniotssl.subscribe({{topic="/ota/device/upgrade/"..key.."/"..name,qos=0}, {topic="/ota/device/upgrade/"..key.."/"..name,qos=1}})
	if not verRpted then		
		--ϱ̼汾Ÿƶ
		verRpt()
	end
end

--[[
upgradeStepRpt
  ¹̼ļؽϱ
  
		step1100ؽȱȣ-2ʧ
		descϢΪջnil
ֵ
]]
local function upgradeStepRpt(step,desc)
	print("upgradeStepRpt",step,desc)
	if step<=0 or step==100 then sys.timer_stop(getPercent) end
	lastStep = step
	aliyuniotssl.publish("/ota/device/progress/"..productKey.."/"..deviceName,"{\"id\":1,\"params\":{\"step\":\""..step.."\",\"desc\":\""..(desc or "").."\"}}")
end

--[[
downloadCb
  ¹̼ļؽĴ
  
		resultؽtrueΪɹfalseΪʧ
		filePath¹̼ļ·ֻresultΪtrueʱ˲
ֵ
]]
local function downloadCb(result,filePath)
	print("downloadCb",gCb,result,filePath,gFileSize,io.filesize(filePath))
	sys.setrestart(true,4)
	sys.timer_stop(sys.setrestart,true,4)
	--ʹõlod汾ڵV0020УMD5
	if result and tonumber(string.match(sys.getcorever(),"Luat_V(%d+)_"))>=20 then
		local calMD5 = crypto.md5(filePath,"file")
		result = (string.upper(calMD5) == string.upper(gFileMD5))
		print("downloadCb cmp md5",result,calMD5,gFileMD5)		
	end
	if gCb then
		gCb(result,filePath)
	else
		if result then sys.restart("ALIYUN_OTA") end
	end
end

local function httpInitConnectCb()
	httpConnectedCb(true)
end

local function httpConnect(init)
	httpClient=https.create(httpHost,443)
	httpClient:connect((init and httpInitConnectCb or httpConnectedCb),httpErrCb)
end

--[[
httpRcvCb
  ջصļ
  resultݽս(˲Ϊ0ʱļ)
				0:ɹ
				1:ʧܣûнϿ
				2:ʾʵ峬ʵʵ壬󣬲ʵ
				3:ճʱ
		statuscodehttpӦ״̬룬stringͻnil
		headhttpӦͷݣtableͻnil
		filename: ļ·
ֵ
]]
local function httpRcvCb(result,statuscode,head,filename)
	print("httpRcvCb",result,statuscode,head,filename)
	gFilePath = filename
	if result==0 then
		upgradeStepRpt(100,result)
		sys.timer_start(downloadCb,3000,true,filename)
		httpClient:destroy()
	else
		httpClient:destroy(httpConnect)
	end
end

--[[
getPercent
  ȡļذٷֱ
  
ֵ
]]
function getPercent()
	local step = httpClient:getrcvpercent()
	if step~=0 and step~=lastStep then
		upgradeStepRpt(step)
	end
	sys.timer_start(getPercent,5000)
end

--[[
httpConnectedCb
  SOCKET connected ɹص
  
		initǷΪ¹̼еĵһ
ֵ
]]
function httpConnectedCb(init)
	local rangeStr = "Range: bytes="..(init and 0 or io.filesize(gFilePath)).."-"
	gFilePath = httpClient:request("GET",httpUrl,{rangeStr},"",httpRcvCb,gPath)
	if init then os.remove(gFilePath) end
	sys.timer_start(getPercent,5000)
end 

--[[
httpErrCb
  SOCKETʧܻص
  
		rstringͣʧԭֵ
		CONNECT: socketһֱʧܣٳԶ
		SENDsocketʧܣٳԶ
ֵ
]]
function httpErrCb(r)
	print("httpErrCb",r)
	upgradeStepRpt(-2,r)
	downloadCb(false)
	httpClient:destroy()	
end

--[[
upgrade
  յƶ˹̼֪ͨϢʱĻص
  
		payloadϢأԭʼ룬յpayloadʲôݣʲôݣûκαת
ֵ
]]
function upgrade(payload)	
	local res,jsonData = pcall(json.decode,payload)
	print("upgrade",res,payload)	
	if res then
		if jsonData.data and jsonData.data.url then
			print("url",jsonData.data.url)
			local host,url = string.match(jsonData.data.url,"https://(.-)/(.+)")
			print("httpUrl",url)
			if host and url then
				httpHost = host
				httpUrl = "/"..url
				httpConnect(true)
			end
			gFileMD5 = jsonData.data.md5
			gFileSize = jsonData.data.size
		end
	end
end

--[[
setVer
  ù̼汾
  
		versionstring̼ͣ汾
ֵ
]]
function setVer(version)
	local oldVer = gVersion
	gVersion = version
	if verRpted and version~=oldVer then		
		verRpted = false
		verRpt()
	end
end

--[[
setName
  ¹̼ļ
  
		namestringͣ¹̼ļ
ֵ
]]
function setName(name)
	gPath = name
end

--[[
setCb
  ¹̼غĻص
  
		cbfunctionͣ¹̼غĻص
ֵ
]]
function setCb(cb)
	gCb = cb
end

sys.setrestart(false,4)
sys.timer_start(sys.setrestart,300000,true,4)
