local m = {}

-- from devicestack Ipc.cpp
local TimeZones = {
    [360] =  "Pacific/Midway",
    [276] =  "Pacific/Niue",
    [32] =  "Pacific/Pago_Pago",
    [387] =  "America/Adak",
    [388] =  "Pacific/Honolulu",
    [359] =  "Pacific/Johnston",
    [117] =  "Pacific/Rarotonga",
    [282] =  "Pacific/Tahiti",
    [283] =  "Pacific/Marquesas",
    [383] =  "America/Anchorage",
    [384] =  "America/Juneau",
    [386] =  "America/Nome",
    [385] =  "America/Yakutat",
    [284] =  "Pacific/Gambier",
    [109] =  "America/Dawson",
    [382] =  "America/Los_Angeles",
    [262] =  "America/Santa_Isabel",
    [261] =  "America/Tijuana",
    [107] =  "America/Vancouver",
    [108] =  "America/Whitehorse",
    [290] =  "Pacific/Pitcairn",
    [379] =  "America/Boise",
    [103] =  "America/Cambridge_Bay",
    [258] =  "America/Chihuahua",
    [106] =  "America/Dawson_Creek",
    [378] =  "America/Denver",
    [102] =  "America/Edmonton",
    [260] =  "America/Hermosillo",
    [105] =  "America/Inuvik",
    [257] =  "America/Mazatlan",
    [259] =  "America/Ojinaga",
    [381] =  "America/Phoenix",
    [380] =  "America/Shiprock",
    [104] =  "America/Yellowknife",
    [82] =  "America/Belize",
    [253] =  "America/Cancun",
    [372] =  "America/Chicago",
    [127] =  "America/Costa_Rica",
    [335] =  "America/El_Salvador",
    [175] =  "America/Guatemala",
    [374] =  "America/Indiana/Knox",
    [373] =  "America/Indiana/Tell_City",
    [271] =  "America/Managua",
    [256] =  "America/Matamoros",
    [375] =  "America/Menominee",
    [254] =  "America/Merida",
    [252] =  "America/Mexico_City",
    [255] =  "America/Monterrey",
    [376] =  "America/North_Dakota/Center",
    [377] =  "America/North_Dakota/New_Salem",
    [99] =  "America/Rainy_River",
    [97] =  "America/Rankin_Inlet",
    [100] =  "America/Regina",
    [95] =  "America/Resolute",
    [101] =  "America/Swift_Current",
    [180] =  "America/Tegucigalpa",
    [98] =  "America/Winnipeg",
    [140] =  "Pacific/Galapagos",
    [96] =  "America/Atikokan",
    [126] =  "America/Bogota",
    [212] =  "America/Cayman",
    [363] =  "America/Detroit",
    [76] =  "America/Eirunepe",
    [338] =  "America/Grand_Turk",
    [139] =  "America/Guayaquil",
    [128] =  "America/Havana",
    [366] =  "America/Indiana/Indianapolis",
    [369] =  "America/Indiana/Marengo",
    [370] =  "America/Indiana/Petersburg",
    [371] =  "America/Indiana/Vevay",
    [367] =  "America/Indiana/Vincennes",
    [368] =  "America/Indiana/Winamac",
    [93] =  "America/Iqaluit",
    [198] =  "America/Jamaica",
    [364] =  "America/Kentucky/Louisville",
    [365] =  "America/Kentucky/Monticello",
    [281] =  "America/Lima",
    [89] =  "America/Montreal",
    [78] =  "America/Nassau",
    [362] =  "America/New_York",
    [91] =  "America/Nipigon",
    [280] =  "America/Panama",
    [94] =  "America/Pangnirtung",
    [182] =  "America/Port-au-Prince",
    [77] =  "America/Rio_Branco",
    [92] =  "America/Thunder_Bay",
    [90] =  "America/Toronto",
    [119] =  "Pacific/Easter",
    [394] =  "America/Caracas",
    [5] =  "America/Anguilla",
    [4] =  "America/Antigua",
    [46] =  "America/Aruba",
    [297] =  "America/Asuncion",
    [50] =  "America/Barbados",
    [88] =  "America/Blanc-Sablon",
    [74] =  "America/Boa_Vista",
    [70] =  "America/Campo_Grande",
    [71] =  "America/Cuiaba",
    [8] =  "America/Curacao",
    [136] =  "America/Dominica",
    [85] =  "America/Glace_Bay",
    [87] =  "America/Goose_Bay",
    [159] =  "America/Grenada",
    [171] =  "America/Guadeloupe",
    [178] =  "America/Guyana",
    [84] =  "America/Halifax",
    [61] =  "America/La_Paz",
    [75] =  "America/Manaus",
    [233] =  "America/Marigot",
    [245] =  "America/Martinique",
    [86] =  "America/Moncton",
    [247] =  "America/Montserrat",
    [350] =  "America/Port_of_Spain",
    [73] =  "America/Porto_Velho",
    [291] =  "America/Puerto_Rico",
    [137] =  "America/Santo_Domingo",
    [58] =  "America/St_Barthelemy",
    [208] =  "America/St_Kitts",
    [220] =  "America/St_Lucia",
    [396] =  "America/St_Thomas",
    [393] =  "America/St_Vincent",
    [168] =  "America/Thule",
    [395] =  "America/Tortola",
    [59] =  "Atlantic/Bermuda",
    [83] =  "America/St_Johns",
    [66] =  "America/Araguaina",
    [20] =  "America/Argentina/Buenos_Aires",
    [25] =  "America/Argentina/Catamarca",
    [21] =  "America/Argentina/Cordoba",
    [23] =  "America/Argentina/Jujuy",
    [26] =  "America/Argentina/La_Rioja",
    [28] =  "America/Argentina/Mendoza",
    [30] =  "America/Argentina/Rio_Gallegos",
    [22] =  "America/Argentina/Salta",
    [29] =  "America/Argentina/San_Luis",
    [27] =  "America/Argentina/San_Juan",
    [24] =  "America/Argentina/Tucuman",
    [31] =  "America/Argentina/Ushuaia",
    [68] =  "America/Bahia",
    [63] =  "America/Belem",
    [161] =  "America/Cayenne",
    [64] =  "America/Fortaleza",
    [165] =  "America/Godthab",
    [67] =  "America/Maceio",
    [289] =  "America/Miquelon",
    [389] =  "America/Montevideo",
    [333] =  "America/Paramaribo",
    [65] =  "America/Recife",
    [72] =  "America/Santarem",
    [118] =  "America/Santiago",
    [69] =  "America/Sao_Paulo",
    [13] =  "Antarctica/Palmer",
    [12] =  "Antarctica/Rothera",
    [151] =  "Atlantic/Stanley",
    [62] =  "America/Noronha",
    [174] =  "Atlantic/South_Georgia",
    [167] =  "America/Scoresbysund",
    [295] =  "Atlantic/Azores",
    [129] =  "Atlantic/Cape_Verde",
    [116] =  "Africa/Abidjan",
    [163] =  "Africa/Accra",
    [238] =  "Africa/Bamako",
    [169] =  "Africa/Banjul",
    [177] =  "Africa/Bissau",
    [229] =  "Africa/Casablanca",
    [170] =  "Africa/Conakry",
    [331] =  "Africa/Dakar",
    [143] =  "Africa/El_Aaiun",
    [329] =  "Africa/Freetown",
    [341] =  "Africa/Lome",
    [223] =  "Africa/Monrovia",
    [246] =  "Africa/Nouakchott",
    [53] =  "Africa/Ouagadougou",
    [334] =  "Africa/Sao_Tome",
    [166] =  "America/Danmarkshavn",
    [147] =  "Atlantic/Canary",
    [155] =  "Atlantic/Faroe",
    [294] =  "Atlantic/Madeira",
    [195] =  "Atlantic/Reykjavik",
    [325] =  "Atlantic/St_Helena",
    [188] =  "Europe/Dublin",
    [162] =  "Europe/Guernsey",
    [190] =  "Europe/Isle_of_Man",
    [197] =  "Europe/Jersey",
    [293] =  "Europe/Lisbon",
    [158] =  "Europe/London",
    [138] =  "Africa/Algiers",
    [113] =  "Africa/Bangui",
    [114] =  "Africa/Brazzaville",
    [146] =  "Africa/Ceuta",
    [120] =  "Africa/Douala",
    [111] =  "Africa/Kinshasa",
    [270] =  "Africa/Lagos",
    [157] =  "Africa/Libreville",
    [9] =  "Africa/Luanda",
    [172] =  "Africa/Malabo",
    [339] =  "Africa/Ndjamena",
    [268] =  "Africa/Niamey",
    [57] =  "Africa/Porto-Novo",
    [347] =  "Africa/Tunis",
    [266] =  "Africa/Windhoek",
    [327] =  "Arctic/Longyearbyen",
    [272] =  "Europe/Amsterdam",
    [1] =  "Europe/Andorra",
    [301] =  "Europe/Belgrade",
    [133] =  "Europe/Berlin",
    [328] =  "Europe/Bratislava",
    [52] =  "Europe/Brussels",
    [183] =  "Europe/Budapest",
    [135] =  "Europe/Copenhagen",
    [164] =  "Europe/Gibraltar",
    [326] =  "Europe/Ljubljana",
    [226] =  "Europe/Luxembourg",
    [145] =  "Europe/Madrid",
    [248] =  "Europe/Malta",
    [230] =  "Europe/Monaco",
    [273] =  "Europe/Oslo",
    [156] =  "Europe/Paris",
    [232] =  "Europe/Podgorica",
    [132] =  "Europe/Prague",
    [196] =  "Europe/Rome",
    [330] =  "Europe/San_Marino",
    [49] =  "Europe/Sarajevo",
    [237] =  "Europe/Skopje",
    [323] =  "Europe/Stockholm",
    [6] =  "Europe/Tirane",
    [221] =  "Europe/Vaduz",
    [392] =  "Europe/Vatican",
    [33] =  "Europe/Vienna",
    [288] =  "Europe/Warsaw",
    [181] =  "Europe/Zagreb",
    [115] =  "Europe/Zurich",
    [251] =  "Africa/Blantyre",
    [56] =  "Africa/Bujumbura",
    [142] =  "Africa/Cairo",
    [80] =  "Africa/Gaborone",
    [405] =  "Africa/Harare",
    [403] =  "Africa/Johannesburg",
    [318] =  "Africa/Kigali",
    [112] =  "Africa/Lubumbashi",
    [404] =  "Africa/Lusaka",
    [265] =  "Africa/Maputo",
    [224] =  "Africa/Maseru",
    [337] =  "Africa/Mbabane",
    [228] =  "Africa/Tripoli",
    [199] =  "Asia/Amman",
    [219] =  "Asia/Beirut",
    [336] =  "Asia/Damascus",
    [292] =  "Asia/Gaza",
    [189] =  "Asia/Jerusalem",
    [131] =  "Asia/Nicosia",
    [173] =  "Europe/Athens",
    [300] =  "Europe/Bucharest",
    [231] =  "Europe/Chisinau",
    [149] =  "Europe/Helsinki",
    [349] =  "Europe/Istanbul",
    [302] =  "Europe/Kaliningrad",
    [354] =  "Europe/Kiev",
    [47] =  "Europe/Mariehamn",
    [227] =  "Europe/Riga",
    [54] =  "Europe/Sofia",
    [141] =  "Europe/Tallinn",
    [355] =  "Europe/Uzhgorod",
    [225] =  "Europe/Vilnius",
    [356] =  "Europe/Zaporozhye",
    [148] =  "Africa/Addis_Ababa",
    [144] =  "Africa/Asmara",
    [353] =  "Africa/Dar_es_Salaam",
    [134] =  "Africa/Djibouti",
    [358] =  "Africa/Kampala",
    [322] =  "Africa/Khartoum",
    [332] =  "Africa/Mogadishu",
    [201] =  "Africa/Nairobi",
    [19] =  "Antarctica/Syowa",
    [401] =  "Asia/Aden",
    [193] =  "Asia/Baghdad",
    [55] =  "Asia/Bahrain",
    [211] =  "Asia/Kuwait",
    [298] =  "Asia/Qatar",
    [319] =  "Asia/Riyadh",
    [81] =  "Europe/Minsk",
    [303] =  "Europe/Moscow",
    [357] =  "Europe/Simferopol",
    [304] =  "Europe/Volgograd",
    [234] =  "Indian/Antananarivo",
    [207] =  "Indian/Comoro",
    [402] =  "Indian/Mayotte",
    [194] =  "Asia/Tehran",
    [48] =  "Asia/Baku",
    [2] =  "Asia/Dubai",
    [279] =  "Asia/Muscat",
    [160] =  "Asia/Tbilisi",
    [7] =  "Asia/Yerevan",
    [305] =  "Europe/Samara",
    [321] =  "Indian/Mahe",
    [249] =  "Indian/Mauritius",
    [299] =  "Indian/Reunion",
    [3] =  "Asia/Kabul",
    [14] =  "Antarctica/Mawson",
    [216] =  "Asia/Aqtau",
    [215] =  "Asia/Aqtobe",
    [346] =  "Asia/Ashgabat",
    [343] =  "Asia/Dushanbe",
    [287] =  "Asia/Karachi",
    [217] =  "Asia/Oral",
    [390] =  "Asia/Samarkand",
    [391] =  "Asia/Tashkent",
    [306] =  "Asia/Yekaterinburg",
    [340] =  "Indian/Kerguelen",
    [250] =  "Indian/Maldives",
    [222] =  "Asia/Colombo",
    [191] =  "Asia/Kolkata",
    [274] =  "Asia/Kathmandu",
    [17] =  "Antarctica/Vostok",
    [213] =  "Asia/Almaty",
    [202] =  "Asia/Bishkek",
    [51] =  "Asia/Dhaka",
    [125] =  "Asia/Kashgar",
    [308] =  "Asia/Novosibirsk",
    [307] =  "Asia/Omsk",
    [214] =  "Asia/Qyzylorda",
    [79] =  "Asia/Thimphu",
    [124] =  "Asia/Urumqi",
    [192] =  "Indian/Chagos",
    [239] =  "Asia/Rangoon",
    [110] =  "Indian/Cocos",
    [15] =  "Antarctica/Davis",
    [342] =  "Asia/Bangkok",
    [397] =  "Asia/Ho_Chi_Minh",
    [241] =  "Asia/Hovd",
    [184] =  "Asia/Jakarta",
    [310] =  "Asia/Krasnoyarsk",
    [309] =  "Asia/Novokuznetsk",
    [203] =  "Asia/Phnom_Penh",
    [185] =  "Asia/Pontianak",
    [218] =  "Asia/Vientiane",
    [130] =  "Indian/Christmas",
    [16] =  "Antarctica/Casey",
    [60] =  "Asia/Brunei",
    [242] =  "Asia/Choibalsan",
    [123] =  "Asia/Chongqing",
    [122] =  "Asia/Harbin",
    [179] =  "Asia/Hong_Kong",
    [311] =  "Asia/Irkutsk",
    [263] =  "Asia/Kuala_Lumpur",
    [264] =  "Asia/Kuching",
    [243] =  "Asia/Macau",
    [186] =  "Asia/Makassar",
    [286] =  "Asia/Manila",
    [121] =  "Asia/Shanghai",
    [324] =  "Asia/Singapore",
    [352] =  "Asia/Taipei",
    [240] =  "Asia/Ulaanbaatar",
    [44] =  "Australia/Perth",
    [45] =  "Australia/Eucla",
    [345] =  "Asia/Dili",
    [187] =  "Asia/Jayapura",
    [209] =  "Asia/Pyongyang",
    [210] =  "Asia/Seoul",
    [200] =  "Asia/Tokyo",
    [312] =  "Asia/Yakutsk",
    [296] =  "Pacific/Palau",
    [42] =  "Australia/Adelaide",
    [39] =  "Australia/Broken_Hill",
    [43] =  "Australia/Darwin",
    [18] =  "Antarctica/DumontDUrville",
    [315] =  "Asia/Magadan",
    [314] =  "Asia/Sakhalin",
    [313] =  "Asia/Vladivostok",
    [40] =  "Australia/Brisbane",
    [36] =  "Australia/Currie",
    [35] =  "Australia/Hobart",
    [41] =  "Australia/Lindeman",
    [37] =  "Australia/Melbourne",
    [38] =  "Australia/Sydney",
    [176] =  "Pacific/Guam",
    [285] =  "Pacific/Port_Moresby",
    [244] =  "Pacific/Saipan",
    [152] =  "Pacific/Truk",
    [34] =  "Australia/Lord_Howe",
    [398] =  "Pacific/Efate",
    [320] =  "Pacific/Guadalcanal",
    [154] =  "Pacific/Kosrae",
    [267] =  "Pacific/Noumea",
    [153] =  "Pacific/Ponape",
    [269] =  "Pacific/Norfolk",
    [10] =  "Antarctica/McMurdo",
    [11] =  "Antarctica/South_Pole",
    [317] =  "Asia/Anadyr",
    [316] =  "Asia/Kamchatka",
    [277] =  "Pacific/Auckland",
    [150] =  "Pacific/Fiji",
    [351] =  "Pacific/Funafuti",
    [236] =  "Pacific/Kwajalein",
    [235] =  "Pacific/Majuro",
    [275] =  "Pacific/Nauru",
    [204] =  "Pacific/Tarawa",
    [361] =  "Pacific/Wake",
    [399] =  "Pacific/Wallis",
    [278] =  "Pacific/Chatham",
    [400] =  "Pacific/Apia",
    [205] =  "Pacific/Enderbury",
    [344] =  "Pacific/Fakaofo",
    [348] =  "Pacific/Tongatapu",
    [206] =  "Pacific/Kiritimati",
    [500] =  "Etc/GMT+12",
    [501] =  "Etc/GMT+11",
    [502] =  "Etc/GMT+10",
    [503] =  "Etc/GMT+9",
    [504] =  "Etc/GMT+8",
    [505] =  "Etc/GMT+7",
    [506] =  "Etc/GMT+6",
    [507] =  "Etc/GMT+5",
    [508] =  "Etc/GMT+4",
    [509] =  "Etc/GMT+3",
    [510] =  "Etc/GMT+2",
    [511] =  "Etc/GMT+1",
    [512] =  "Etc/GMT",
    [513] =  "Etc/GMT-1",
    [514] =  "Etc/GMT-2",
    [515] =  "Etc/GMT-3",
    [516] =  "Etc/GMT-4",
    [517] =  "Etc/GMT-5",
    [518] =  "Etc/GMT-6",
    [519] =  "Etc/GMT-7",
    [520] =  "Etc/GMT-8",
    [521] =  "Etc/GMT-9",
    [522] =  "Etc/GMT-10",
    [523] =  "Etc/GMT-11",
    [524] =  "Etc/GMT-12",
    [0] =  "UTC"
}

-- default co-mapping based on current PDB
m.CO = {}
m.CO.timeCo     = 50
m.CO.dateCo     = 51
m.CO.dateTimeCo = 52
m.CO.triggerCo  = 53
m.CO.ntpCo      = 54

function m.AddCosToMap()
    Logger:Info("-- timemanager_module.lua: add COs")
    local urn = deviceUrn_base .. ":TimeManager-App:"
    helper.AddAssociatedCoToMap(m.CO.timeCo, "CRT", "10.001", urn .. "Time")
    helper.AddAssociatedCoToMap(m.CO.dateCo, "CRT", "11.001", urn .. "Date")
    helper.AddAssociatedCoToMap(m.CO.dateTimeCo, "CRT", "19.001", urn .. "DateTime")
    helper.AddAssociatedCoToMap(m.CO.triggerCo, "WC", "1.017", urn .. "TriggerDateTime")
    helper.AddAssociatedCoToMap(m.CO.ntpCo, "CRT", "1.002", urn .. "NtpRequestStatus")
end

function m.Configure(config)
	Logger:Info("-- timemanager_module.lua: configure parameter")
    helper.LogConfiguration("TimeManager-App", config)   
    local channel = device:AddChannel("TimeManager-App")
    local sendInterval = { [0] = "minute", [1] = "hour", [2] = "day" }
    channel.Enabled = config.EnabledBool
    if  channel.Enabled then
        channel:AddParameterSet("TimeManager", "SendTimeInterval", sendInterval[config.SendTimeInterval])
        channel:AddParameterSet("TimeManager", "SendDateInterval", sendInterval[config.SendDateInterval])
    end
    if config.TimezonePDBId ~= nil then
      -- due to historic reasons the id has the UTC offset coded in the upper bits...
      -- Now we could use this to read old PDBs without conversion
      local timeZoneId = config.TimezonePDBId & 1023
      local timeZone = TimeZones[timeZoneId]
      Logger:Info(string.format("Using time zone %s", timeZone))
      channel:AddParameterSet("TimeManager", "TimeZone", timeZone)
      channel:AddParameterSet("TimeManager", "TimeZoneId", timeZoneId)
    end
end

return m
