-- Plugin for converting channels lists from neutrino receivers
-- Author focus.cst@gmail.com
-- License GPL v2
-- Copyright (C) 2013 CoolStream International Ltd

-- flag to test as plain script, without xupnpd - cfg not defined in this case
local cst_test = false

if not cfg then
cfg={}
cfg.tmp_path='/tmp/'
cfg.feeds_path='/tmp/'
cfg.debug=1
cst_test = true
end

function trim(s)
	return (s:gsub("^%s*(.-)%s*$", "%1"))
end

function cst_debug(level, msg)
	if cfg.debug>level then
		print(msg)
	end
end

function isFile(name)
	if type(name)~="string" then return false end
	local f = io.open(name)
	if f then
		f:close()
		return true
	end
	return false
end

function cst_get_logo_hdd_dir()
	local d = nil
	local f = io.open("/var/tuxbox/config/neutrino.conf", "r")
	if f then
		for line in f:lines() do
			local _d = line:match("logo_hdd_dir=(.*)")
			if _d then
				d = _d
				goto continue
			end
		end
		::continue::
		f:close()
	end
	if d then
		cst_debug(0, "cst_get_logo_hdd_dir: logo_hdd_dir="..d)
	end
	return d
end

local logo_hdd_dir = cst_get_logo_hdd_dir()
local logo_flash_dir = "/usr/share/tuxbox/neutrino/icons/logo"
local logo_flash_dir_var = "/var/tuxbox/icons/logo"

function cst_get_logo(id, name)
	Path = {logo_hdd_dir, logo_flash_dir_var, logo_flash_dir}
	local x=5
	if string.sub(id ,5,5) == '0' then
		x = x + 1
		if string.sub(id ,6,6) == '0' then
			x = x + 1
			if string.sub(id ,7,7) == '0' then
				x = x + 1
			end
		end
	end
	id = string.sub(id ,x,16)

	chan = {name,id}
	for v, varPath in pairs(Path) do
		for v2, varChan in pairs(chan) do
			file = varPath .."/" .. varChan
			if isFile(file .. ".png") then
				return file .. ".png"
			end
			if isFile(file .. ".jpg") then
				return file .. ".jpg"
			end
		end
	end
	return nil
end

function cst_get_bouquets(s)
	local btable={}
	for string in string.gmatch(s, "(.-)%c") do
		if string then
			cst_debug(1, "########## bouquet="..string)
			local num = string.match(string, "%d+");
			if num then
				local len = string.len(num);
				local name = string.sub(string, len+1);
				btable[num] = name
				cst_debug(1, "num="..num.." name="..btable[num]);
			end
			--break; -- one bouquet
		end
	end
	return btable
end

function cst_get_channels(s)
	local ctable={}
	for string in string.gmatch(s, "(.-)%c") do
		idx = 1;
		if string then
			cst_debug(1, "########## channel="..string)
			local num = string.match(string, "%d+");
			if num then
				local len = string.len(num);
				local rest = string.sub(string, len+1);
				local id = string.match(rest, "%x+ ");
				len = string.len(id);
				local name = string.sub(rest, len+2);
				cst_debug(1, "num="..num.." id="..id.." name="..name)
				if id and name then
					table.insert(ctable, {id, name});
					idx = idx + 1;
				end
			end
		end
	end
	return ctable
end

function cst_read_url(url)
	local string = ""
	cst_debug(0, "url: "..url)
	if cst_test then
		local wget = "wget -q -O- "
		local turl = wget.."\""..url.."\""
		local file = io.popen(turl)
		repeat
			local st = file:read()
			if st then
				string = string..st.."\n";
			end
		until not st
		file:close()
	else
		string = http.download(url)
	end

	if string == nil then
		string =""
	end
	cst_debug(0, "url read: "..string.len(string))
	return string
end

function cst_save_bouqutes(feed, friendly_name, mode, sysip)
	local rc=false
	local feedspath = cfg.feeds_path

	local cst_url = 'http://'..feed..'/control/'
	local burl = "getbouquets?fav=true&mode="..mode
	local curl = "getbouquet?epg=true&mode="..mode.."&bouquet="

	local bouquets_data = cst_read_url(cst_url..burl)
	local bouquets = cst_get_bouquets(bouquets_data)

	if not bouquets then
		return rc
	end

	local bindex
	local bouquett = {}
	for bindex,bouquett in pairs(bouquets) do
		local cindex
		local channelt = {}
		local xmlbouquet_data = cst_read_url(cst_url..curl..bindex)
		local bouquet = cst_get_channels(xmlbouquet_data)
		if bouquet then
			local bnum = string.format("%03d", bindex)
			local m3ufilename = cfg.tmp_path.."cst_"..friendly_name.."_"..mode.."_bouquet_"..bnum..".m3u"
			cst_debug(0, m3ufilename)
			local m3ufile = io.open(m3ufilename,"w")
			m3ufile:write("#EXTM3U name=\""..friendly_name..": "..mode.." - "..trim(bouquett).."\" plugin=neutrino type=ts\n")
			for cindex,channelt in pairs(bouquet) do
				local id = channelt[1];
				local name = channelt[2];

				local logo = cst_get_logo(id, name)
				if logo == nil then
					m3ufile:write("#EXTINF:0,"..name.."\n")
				else
					m3ufile:write("#EXTINF:0 logo="..sysip..logo .." ,"..name.."\n")
				end

				-- m3ufile:write(cst_url.."zapto?"..id.."\n")
				m3ufile:write("http://"..feed..":31339/id="..id.."\n")
			end
			m3ufile:close()
			os.execute(string.format('mv %s %s',m3ufilename,feedspath))
			rc=true
		end
	end
	return rc
end

function cst_updatefeed(feed,friendly_name)
	local rc=false
	if not friendly_name then
		friendly_name = feed
	end

	local sysip = ""
	if not cst_test then
		sysip = www_location
		sysip = sysip:match('(http://%d*.%d*.%d*.%d*):*.')
	end
	if cst_save_bouqutes(feed, friendly_name, "TV", sysip) then
		rc = true
	end
	if cst_save_bouqutes(feed, friendly_name, "RADIO", sysip) then
		rc = true
	end

	return rc
end

function cst_zapto(urlbase,id)
	local zap = urlbase.."/control/zapto?"..id;
	cst_read_url(zap)
end

function cst_sendurl(cst_url,range)
	local i,j,baseurl = string.find(cst_url,"(.+):.+")
	cst_debug(0, "cst_sendurl: url="..cst_url.." baseurl="..baseurl)

--	i,j,id = string.find(cst_url,".*id=(.+)")
--	local surl = baseurl.."/control/standby"
--	local standby = cst_read_url(surl)

--	if standby then
--		cst_debug(0, "standby="..standby)
--
--		-- wakeup from standby
--		if string.find(standby,"on") then
--			cst_read_url(surl.."?off&cec=off")
--		end
--	end
--	-- zap to channel
--	cst_zapto(baseurl,id)

	if not cst_test then
		plugin_sendurl(cst_url,cst_url,range)
	end
end

if cst_test then
cst_updatefeed("172.16.1.20","tank")
-- cst_updatefeed("172.16.1.10","tank")
-- cst_sendurl("http://172.16.1.20:31339/id=c1f000010070277a", 0)
end

if not cst_test then
plugins['neutrino']={}
plugins.neutrino.name="Neutrino"
plugins.neutrino.desc="IP address (example: <i>192.168.0.1</i>)"
plugins.neutrino.updatefeed=cst_updatefeed
plugins.neutrino.sendurl=cst_sendurl
end
