<?xml version="1.0" encoding="utf-8"?>

<%
-- Cisco ATA Configuration File Template
local values = ...

--[[ -- Parameters
values["device"]["adminpassword"] = ""
values["device"]["digitmap"] = ""
values["device"]["mac"] = ""
values["device"]["musiconhold"] = ""
values["device"]["registrar"] = ""
values["device"]["sntpserver"] = ""
values["device"]["template"] = "/etc/provisioning/templates/ciscoata-template.lua"
values["device"]["timezone"] = ""
values["regX"]["callerid"] = ""
values["regX"]["extension"] = ""
values["regX"]["forwardall"] = ""
values["regX"]["forwardallenable"] = boolean
values["regX"]["forwardbusy"] = ""
values["regX"]["forwardbusyenable"] = boolean
values["regX"]["forwardnoanswer"] = ""
values["regX"]["forwardnoanswerenable"] = boolean
values["regX"]["password"] = ""
-- Unimplemented -- values["services"]["callhistoryenable"] = boolean
values["services"]["callwaitingenable"] = boolean
values["services"]["forwarding"] = boolean
values["services"]["hotlineenable"] = boolean
-- Unimplemented -- values["services"]["mailbox"] = ""
-- Unimplemented -- values["services"]["mailcallback"] = ""
-- Unimplemented -- values["services"]["speeddialenable"] = boolean
--]]

local function yesno ( bool )
	if bool then
		return "Yes"
	else
		return "No"
	end
end

local function xml_elem(elem,value,permissions,i)
        local e = elem
        if i then e = elem.."_"..tostring(i).."_" end
        local output = {"<", e, ' ua="'}
        output[#output+1] = (permissions or "na")..'">'
        if type(value) == "boolean" then
                output[#output+1] = yesno(value)
        elseif value then
                output[#output+1] = value
        end
        output[#output+1] = "</"..e..">"
        io.write(table.concat(output).."\n")
end
%>

<flat-profile>

<%
-- Device parameters
xml_elem("Web_Login_Admin_Password", values.device.adminpassword, "na")
xml_elem("Web_Login_Guest_Password", values.device.adminpassword, "na")
xml_elem("IVR_Admin_Password", values.device.adminpassword, "na")
%>

<Time_Setup>
<%
if values.device.sntpserver then
	xml_elem("Time_Server_Mode", "manual", "na")
	xml_elem("Time_Server", values.device.sntpserver, "na")
end

-- Handle Time Zone parameter
--   See http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
--     TZ variable, with no leading colon
--   Syntax: stdoffset[dst[offset][,start[/time],end[/time]]]
--   Examples: 'GMT0' 'EST5EDT,M3.2.0,M11.1.0' '<GMT+5>5'
--  Parse time zone variable
posixtz = require('posixtz')
local tz = posixtz.parse(values.device.timezone)
if tz then
	-- The Cisco doc gives a static list of 42 possible timezones with no explanations
	-- First is obviously offset from GMT (with reverse sign from posixtz)
	-- Second seems to be enumeration of entries with same offset
	-- Third must be the start/stop of daylight saving time (0-10, no 3)
	-- Just pick the closest
	local dst = {	[1] = {start="M3.2.0", stop="M11.1.0"},		-- 1 -- United States
			[2] = {start="M3.5.0", stop="M10.5.0"},		-- 2 -- Europe
			-- 4 is used for several locations that don't do dst from what I can tell
			[4] = {start="M9.5.0", stop="M4.1.0"},		-- 4 -- New Zealand
			[5] = {start="M4.1.0", stop="M10.5.0"},		-- 5 -- Mexico
		--	[10] = {start="M10.1.0", stop="M4.1.0"},	-- 10 -- South Australia -- Not needed
			-- Don't know what 6-9 are for, since those locations don't have dst from what I can tell
	}

	-- Here are the 42 possible timezones	-- UI Name					Value			Corresponding parameter
	local timezones = {["-11"] = {0},	-- Midway Island, Samoa				"-11 1 0"		0
			["-10"] = {0},		-- Hawaii					"-10 1 0"		0
			["-09"] = {1},		-- Alaska					"-09 1 1"		AKST9AKDT,M3.2.0,M11.1.0
			["-08"] = {1},		-- Pacific Time (USA & Canada)			"-08 1 1"		PST8PDT,M3.2.0,M11.1.0
			["-07"] = {0, 1},	-- Arizona					"-07 1 0"		0
						-- Mountain Time (USA & Canada)			"-07 2 1",		MST7MDT,M3.2.0,M11.1.0
			["-06"] = {5, 1},	-- Mexico					"-06 1 5"		CST6CDT,M4.1.0,M10.5.0
						-- Central Time (USA & Canada)			"-06 2 1"		CST6CDT,M3.2.0,M11.1.0
			["-05"] = {0, 1},	-- Indiana East, Columbia, Panama		"-05 1 0"		0
						-- Eastern Time (USA & Canada)			"-05 2 1"		EST5EDT,M3.2.0,M11.1.0
			["-04"] = {0, 1, 0},	-- Bolivia, Venezuela				"-04 1 0"		0
						-- Atlantic Time (Canada), Brazil West		"-04 2 1"		AST4ADT,M3.2.0,M11.1.0
						-- Guyana					"-04 3 0"		0
		--	["-03.5"] = {1},	-- Newfoundland					"-03.5 1 1"		NST3:30NDT,M3.2.0,M11.1.0
			["-03"] = {1},		-- Brazil East, Greenland			"-03 1 1"		?
			["-02"] = {0},		-- Mid-Atlantic					"-02 1 0"		0
			["-01"] = {2},		-- Azores					"-01 1 2"		AZOT1AZOST,M3.5.0/0,M10.5.0/1
			["+00"] = {0, 2},	-- Gambia, Liberia, Morocco			"+00 1 0"		0
						-- England					"+00 2 2"		GMT0BST,M3.5.0/1,M10.5.0
			["+01"] = {6, 2},	-- Tunisia					"+01 1 6"		0
						-- France, Germany, Italy			"+01 2 2"		CET-1CEST,M3.5.0,M10.5.0/3
			["+02"] = {0, 2},	-- South Africa					"+02 1 0"		0
						-- Greece, Ukraine, Romania, Turkey		"+02 2 2"		EET-2EEST,M3.5.0/3,M10.5.0/4
			["+03"] = {8, 9},	-- Iraq, Kuwait					"+03 1 8"		0
						-- Jordan					"+03 2 9"		?
			["+04"] = {0},		-- ABU Dhabi, Muscat, Armenia			"+04 1 0"		0
			["+05"] = {7},		-- Pakistan, Russia				"+05 1 7"		0
		--	["+05.5"] = {0},	-- Bombay, Calcutta, Madras, New Delhi		"+05.5 1 0"		0
			["+06"] = {7},		-- Bangladesh, Russia				"+06 1 7"		0
			["+07"] = {7},		-- Thailand, Russia				"+07 1 7"		0
			["+08"] = {4, 7, 0, 0},	-- Australia Western				"+08 1 4"		0 
						-- Russia					"+08 2 7"		?
						-- China, Hong Kong				"+08 3 0"		0
						-- Singapore, Taiwan				"+08 4 0"		0
			["+09"] = {0},		-- Japan, Korea					"+09 1 0"		0
		--	["+09.5"] = {10},	-- South Australia				"+09.5 1 10"		CST-9:30CST,M10.1.0,M4.1.0/3
			["+10"] = {7, 4},	-- Guam, Russia					"+10 1 7"		0
						-- Australia					"+10 2 4"		
			["+11"] = {0},		-- Soloman Islands				"+11 1 0"		0
			["+12"] = {0, 4, 0},	-- Fiji						"+12 1 0"		?
						-- New Zealand					"+12 2 4"		NZST-12NZDT,M9.5.0,M4.1.0/3
						-- Kwajalein					"+12 3 0"		0
	}
	-- convert POSIX sign (W of GMT is '+') to Cisco (E of GMT is '+')
	if tonumber(tz.offset.hour) == 0 then
		tz.offset.sign = "+"
	else
		if tz.offset.sign == "-" then
			tz.offset.sign = "+"
		else
			tz.offset.sign = "-"
		end
	end

	local offset = string.format("%s%02i", tz.offset.sign, tz.offset.hour)

	if timezones[offset] and #timezones[offset] == 1 then
		xml_elem("Time_Zone", offset.." 1 "..timezones[offset][1], "na")
	elseif timezones[offset] then
		-- We need to pick the dst that matches the closest
		local match = 0 -- default to no dst
		if tz.dst then
			for i,t in ipairs(dst) do
				if string.find(values.device.timezone, t.start) and string.find(values.device.timezone, t.stop) then
					match = i
					break
				end
			end
		end
		local index = 1 -- default to first option in this timezone
		for i,t in ipairs(timezones[offset]) do
			if t == match then
				index = i
				break
			end
		end
		xml_elem("Time_Zone", offset.." "..index.." "..timezones[offset][index], "na")
	else
		-- Just don't set it
	end
	
	if tz.dst then
		xml_elem("Auto_Adjust_Clock", true, "na")
	else
		xml_elem("Auto_Adjust_Clock", false, "na")
	end
end
%>
</Time_Setup>

<%
for pg, pg_t in pairs(values) do
	-- Is it of the form regX ?
	local num = string.match(pg, 'reg(%d+)')
	if num then
		if pg_t.extension ~= "" then
			xml_elem("Line_Enable", true, "na", num)
			xml_elem("MOH_Server", values.device.musiconhold, "na", num)
			xml_elem("Proxy", values.device.registrar, "na", num)
			xml_elem("Call_Waiting_Serv", (values.services and values.services.callwaitingenable), "na", num)
			xml_elem("CW_Setting", (values.services and values.services.callwaitingenable), "na", num)
			if values.services and values.services.hotlineenable then
				-- Need to escape < and >
				xml_elem("Dial_Plan", "( P1&lt;:"..values.services.hotlinedestination.."&gt; )", "na", num)
			elseif values.device and values.device.digitmap and values.device.digitmap ~= "" then
				xml_elem("Dial_Plan", "( "..values.device.digitmap.." )", "na", num)
			else
				xml_elem("Dial_Plan", "( x. )", "na", num)
			end

			if pg_t.callerid == "" then
				pg_t.callerid = pg_t.extension
			end
			xml_elem("Display_Name", pg_t.callerid, "na", num)
			xml_elem("User_ID", pg_t.extension, "na", num)
			xml_elem("Password", pg_t.password, "na", num)

			local forwarding = {	{param="forwardall", xml="Cfwd_All_"},
						{param="forwardbusy", xml="Cfwd_Busy_"},
						{param="forwardnoanswer", xml="Cfwd_No_Ans_"} }
			for i,f in ipairs(forwarding) do
				if values.services and values.services.forwarding and pg_t[f.param.."enable"] then
					xml_elem(f.xml.."Serv", true, "na", num)
					xml_elem(f.xml.."Dest", pg_t[f.param], "na", num)
				else
					xml_elem(f.xml.."Serv", false, "na", num)
					xml_elem(f.xml.."Dest", "", "na", num)
				end
			end
			if values.services and values.services.forwarding and pg_t.forwardnoanswerenable then
				xml_elem("Cfwd_No_Ans_Delay", "20", "na", num)
			else
				xml_elem("Cfwd_No_Ans_Delay", "", "na", num)
			end
		else
			-- Cannot disable the lines, or check-sync will not work, just set User ID to ""
			xml_elem("Line_Enable", true, "na", num)
			xml_elem("User_ID", "", "na", num)
		end
	end
end %>

</flat-profile>

<%
-- DEBUGGING
--require("session")
--io.write(session.serialize("values", values))
%>
