"""A dict to translate from IANA location name to Windows timezone name. Translations taken from CLDR_WINZONE_URL
"""
import re

import requests

from .util import to_xml

CLDR_WINZONE_URL = "https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml"
DEFAULT_TERRITORY = "001"
CLDR_WINZONE_TYPE_VERSION = "2021a"
CLDR_WINZONE_OTHER_VERSION = "7e11800"


def generate_map(timeout=10):
    """Create a new CLDR_TO_MS_TIMEZONE_MAP map from the CLDR data. Used when the CLDR database is updated.

    :param timeout:  (Default value = 10)
    :return:
    """
    r = requests.get(CLDR_WINZONE_URL, timeout=timeout)
    if r.status_code != 200:
        raise ValueError(f"Unexpected response: {r}")
    tz_map = {}
    timezones_elem = to_xml(r.content).find("windowsZones").find("mapTimezones")
    type_version = timezones_elem.get("typeVersion")
    other_version = timezones_elem.get("otherVersion")
    for e in timezones_elem.findall("mapZone"):
        for location in re.split(r"\s+", e.get("type")):
            if e.get("territory") == DEFAULT_TERRITORY or location not in tz_map:
                # Prefer default territory. This is so MS_TIMEZONE_TO_IANA_MAP maps from MS timezone ID back to the
                # "preferred" region/location timezone name.
                tz_map[location] = e.get("other"), e.get("territory")
    return type_version, other_version, tz_map


# This map is generated irregularly from generate_map(). Do not edit manually - make corrections to
# IANA_TO_MS_TIMEZONE_MAP instead. We provide this map to avoid hammering the CLDR_WINZONE_URL.
#
# This list was generated from CLDR_WINZONE_URL version CLDR_WINZONE_VERSION.
CLDR_TO_MS_TIMEZONE_MAP = {
    "Africa/Abidjan": ("Greenwich Standard Time", "CI"),
    "Africa/Accra": ("Greenwich Standard Time", "GH"),
    "Africa/Addis_Ababa": ("E. Africa Standard Time", "ET"),
    "Africa/Algiers": ("W. Central Africa Standard Time", "DZ"),
    "Africa/Asmera": ("E. Africa Standard Time", "ER"),
    "Africa/Bamako": ("Greenwich Standard Time", "ML"),
    "Africa/Bangui": ("W. Central Africa Standard Time", "CF"),
    "Africa/Banjul": ("Greenwich Standard Time", "GM"),
    "Africa/Bissau": ("Greenwich Standard Time", "GW"),
    "Africa/Blantyre": ("South Africa Standard Time", "MW"),
    "Africa/Brazzaville": ("W. Central Africa Standard Time", "CG"),
    "Africa/Bujumbura": ("South Africa Standard Time", "BI"),
    "Africa/Cairo": ("Egypt Standard Time", "001"),
    "Africa/Casablanca": ("Morocco Standard Time", "001"),
    "Africa/Ceuta": ("Romance Standard Time", "ES"),
    "Africa/Conakry": ("Greenwich Standard Time", "GN"),
    "Africa/Dakar": ("Greenwich Standard Time", "SN"),
    "Africa/Dar_es_Salaam": ("E. Africa Standard Time", "TZ"),
    "Africa/Djibouti": ("E. Africa Standard Time", "DJ"),
    "Africa/Douala": ("W. Central Africa Standard Time", "CM"),
    "Africa/El_Aaiun": ("Morocco Standard Time", "EH"),
    "Africa/Freetown": ("Greenwich Standard Time", "SL"),
    "Africa/Gaborone": ("South Africa Standard Time", "BW"),
    "Africa/Harare": ("South Africa Standard Time", "ZW"),
    "Africa/Johannesburg": ("South Africa Standard Time", "001"),
    "Africa/Juba": ("South Sudan Standard Time", "001"),
    "Africa/Kampala": ("E. Africa Standard Time", "UG"),
    "Africa/Khartoum": ("Sudan Standard Time", "001"),
    "Africa/Kigali": ("South Africa Standard Time", "RW"),
    "Africa/Kinshasa": ("W. Central Africa Standard Time", "CD"),
    "Africa/Lagos": ("W. Central Africa Standard Time", "001"),
    "Africa/Libreville": ("W. Central Africa Standard Time", "GA"),
    "Africa/Lome": ("Greenwich Standard Time", "TG"),
    "Africa/Luanda": ("W. Central Africa Standard Time", "AO"),
    "Africa/Lubumbashi": ("South Africa Standard Time", "CD"),
    "Africa/Lusaka": ("South Africa Standard Time", "ZM"),
    "Africa/Malabo": ("W. Central Africa Standard Time", "GQ"),
    "Africa/Maputo": ("South Africa Standard Time", "MZ"),
    "Africa/Maseru": ("South Africa Standard Time", "LS"),
    "Africa/Mbabane": ("South Africa Standard Time", "SZ"),
    "Africa/Mogadishu": ("E. Africa Standard Time", "SO"),
    "Africa/Monrovia": ("Greenwich Standard Time", "LR"),
    "Africa/Nairobi": ("E. Africa Standard Time", "001"),
    "Africa/Ndjamena": ("W. Central Africa Standard Time", "TD"),
    "Africa/Niamey": ("W. Central Africa Standard Time", "NE"),
    "Africa/Nouakchott": ("Greenwich Standard Time", "MR"),
    "Africa/Ouagadougou": ("Greenwich Standard Time", "BF"),
    "Africa/Porto-Novo": ("W. Central Africa Standard Time", "BJ"),
    "Africa/Sao_Tome": ("Sao Tome Standard Time", "001"),
    "Africa/Tripoli": ("Libya Standard Time", "001"),
    "Africa/Tunis": ("W. Central Africa Standard Time", "TN"),
    "Africa/Windhoek": ("Namibia Standard Time", "001"),
    "America/Adak": ("Aleutian Standard Time", "001"),
    "America/Anchorage": ("Alaskan Standard Time", "001"),
    "America/Anguilla": ("SA Western Standard Time", "AI"),
    "America/Antigua": ("SA Western Standard Time", "AG"),
    "America/Araguaina": ("Tocantins Standard Time", "001"),
    "America/Argentina/La_Rioja": ("Argentina Standard Time", "AR"),
    "America/Argentina/Rio_Gallegos": ("Argentina Standard Time", "AR"),
    "America/Argentina/Salta": ("Argentina Standard Time", "AR"),
    "America/Argentina/San_Juan": ("Argentina Standard Time", "AR"),
    "America/Argentina/San_Luis": ("Argentina Standard Time", "AR"),
    "America/Argentina/Tucuman": ("Argentina Standard Time", "AR"),
    "America/Argentina/Ushuaia": ("Argentina Standard Time", "AR"),
    "America/Aruba": ("SA Western Standard Time", "AW"),
    "America/Asuncion": ("Paraguay Standard Time", "001"),
    "America/Bahia": ("Bahia Standard Time", "001"),
    "America/Bahia_Banderas": ("Central Standard Time (Mexico)", "MX"),
    "America/Barbados": ("SA Western Standard Time", "BB"),
    "America/Belem": ("SA Eastern Standard Time", "BR"),
    "America/Belize": ("Central America Standard Time", "BZ"),
    "America/Blanc-Sablon": ("SA Western Standard Time", "CA"),
    "America/Boa_Vista": ("SA Western Standard Time", "BR"),
    "America/Bogota": ("SA Pacific Standard Time", "001"),
    "America/Boise": ("Mountain Standard Time", "US"),
    "America/Buenos_Aires": ("Argentina Standard Time", "001"),
    "America/Cambridge_Bay": ("Mountain Standard Time", "CA"),
    "America/Campo_Grande": ("Central Brazilian Standard Time", "BR"),
    "America/Cancun": ("Eastern Standard Time (Mexico)", "001"),
    "America/Caracas": ("Venezuela Standard Time", "001"),
    "America/Catamarca": ("Argentina Standard Time", "AR"),
    "America/Cayenne": ("SA Eastern Standard Time", "001"),
    "America/Cayman": ("SA Pacific Standard Time", "KY"),
    "America/Chicago": ("Central Standard Time", "001"),
    "America/Chihuahua": ("Mountain Standard Time (Mexico)", "001"),
    "America/Coral_Harbour": ("SA Pacific Standard Time", "CA"),
    "America/Cordoba": ("Argentina Standard Time", "AR"),
    "America/Costa_Rica": ("Central America Standard Time", "CR"),
    "America/Creston": ("US Mountain Standard Time", "CA"),
    "America/Cuiaba": ("Central Brazilian Standard Time", "001"),
    "America/Curacao": ("SA Western Standard Time", "CW"),
    "America/Danmarkshavn": ("Greenwich Standard Time", "GL"),
    "America/Dawson": ("Yukon Standard Time", "CA"),
    "America/Dawson_Creek": ("US Mountain Standard Time", "CA"),
    "America/Denver": ("Mountain Standard Time", "001"),
    "America/Detroit": ("Eastern Standard Time", "US"),
    "America/Dominica": ("SA Western Standard Time", "DM"),
    "America/Edmonton": ("Mountain Standard Time", "CA"),
    "America/Eirunepe": ("SA Pacific Standard Time", "BR"),
    "America/El_Salvador": ("Central America Standard Time", "SV"),
    "America/Fort_Nelson": ("US Mountain Standard Time", "CA"),
    "America/Fortaleza": ("SA Eastern Standard Time", "BR"),
    "America/Glace_Bay": ("Atlantic Standard Time", "CA"),
    "America/Godthab": ("Greenland Standard Time", "001"),
    "America/Goose_Bay": ("Atlantic Standard Time", "CA"),
    "America/Grand_Turk": ("Turks And Caicos Standard Time", "001"),
    "America/Grenada": ("SA Western Standard Time", "GD"),
    "America/Guadeloupe": ("SA Western Standard Time", "GP"),
    "America/Guatemala": ("Central America Standard Time", "001"),
    "America/Guayaquil": ("SA Pacific Standard Time", "EC"),
    "America/Guyana": ("SA Western Standard Time", "GY"),
    "America/Halifax": ("Atlantic Standard Time", "001"),
    "America/Havana": ("Cuba Standard Time", "001"),
    "America/Hermosillo": ("US Mountain Standard Time", "MX"),
    "America/Indiana/Knox": ("Central Standard Time", "US"),
    "America/Indiana/Marengo": ("US Eastern Standard Time", "US"),
    "America/Indiana/Petersburg": ("Eastern Standard Time", "US"),
    "America/Indiana/Tell_City": ("Central Standard Time", "US"),
    "America/Indiana/Vevay": ("US Eastern Standard Time", "US"),
    "America/Indiana/Vincennes": ("Eastern Standard Time", "US"),
    "America/Indiana/Winamac": ("Eastern Standard Time", "US"),
    "America/Indianapolis": ("US Eastern Standard Time", "001"),
    "America/Inuvik": ("Mountain Standard Time", "CA"),
    "America/Iqaluit": ("Eastern Standard Time", "CA"),
    "America/Jamaica": ("SA Pacific Standard Time", "JM"),
    "America/Jujuy": ("Argentina Standard Time", "AR"),
    "America/Juneau": ("Alaskan Standard Time", "US"),
    "America/Kentucky/Monticello": ("Eastern Standard Time", "US"),
    "America/Kralendijk": ("SA Western Standard Time", "BQ"),
    "America/La_Paz": ("SA Western Standard Time", "001"),
    "America/Lima": ("SA Pacific Standard Time", "PE"),
    "America/Los_Angeles": ("Pacific Standard Time", "001"),
    "America/Louisville": ("Eastern Standard Time", "US"),
    "America/Lower_Princes": ("SA Western Standard Time", "SX"),
    "America/Maceio": ("SA Eastern Standard Time", "BR"),
    "America/Managua": ("Central America Standard Time", "NI"),
    "America/Manaus": ("SA Western Standard Time", "BR"),
    "America/Marigot": ("SA Western Standard Time", "MF"),
    "America/Martinique": ("SA Western Standard Time", "MQ"),
    "America/Matamoros": ("Central Standard Time", "MX"),
    "America/Mazatlan": ("Mountain Standard Time (Mexico)", "MX"),
    "America/Mendoza": ("Argentina Standard Time", "AR"),
    "America/Menominee": ("Central Standard Time", "US"),
    "America/Merida": ("Central Standard Time (Mexico)", "MX"),
    "America/Metlakatla": ("Alaskan Standard Time", "US"),
    "America/Mexico_City": ("Central Standard Time (Mexico)", "001"),
    "America/Miquelon": ("Saint Pierre Standard Time", "001"),
    "America/Moncton": ("Atlantic Standard Time", "CA"),
    "America/Monterrey": ("Central Standard Time (Mexico)", "MX"),
    "America/Montevideo": ("Montevideo Standard Time", "001"),
    "America/Montreal": ("Eastern Standard Time", "CA"),
    "America/Montserrat": ("SA Western Standard Time", "MS"),
    "America/Nassau": ("Eastern Standard Time", "BS"),
    "America/New_York": ("Eastern Standard Time", "001"),
    "America/Nipigon": ("Eastern Standard Time", "CA"),
    "America/Nome": ("Alaskan Standard Time", "US"),
    "America/Noronha": ("UTC-02", "BR"),
    "America/North_Dakota/Beulah": ("Central Standard Time", "US"),
    "America/North_Dakota/Center": ("Central Standard Time", "US"),
    "America/North_Dakota/New_Salem": ("Central Standard Time", "US"),
    "America/Ojinaga": ("Mountain Standard Time", "MX"),
    "America/Panama": ("SA Pacific Standard Time", "PA"),
    "America/Pangnirtung": ("Eastern Standard Time", "CA"),
    "America/Paramaribo": ("SA Eastern Standard Time", "SR"),
    "America/Phoenix": ("US Mountain Standard Time", "001"),
    "America/Port-au-Prince": ("Haiti Standard Time", "001"),
    "America/Port_of_Spain": ("SA Western Standard Time", "TT"),
    "America/Porto_Velho": ("SA Western Standard Time", "BR"),
    "America/Puerto_Rico": ("SA Western Standard Time", "PR"),
    "America/Punta_Arenas": ("Magallanes Standard Time", "001"),
    "America/Rainy_River": ("Central Standard Time", "CA"),
    "America/Rankin_Inlet": ("Central Standard Time", "CA"),
    "America/Recife": ("SA Eastern Standard Time", "BR"),
    "America/Regina": ("Canada Central Standard Time", "001"),
    "America/Resolute": ("Central Standard Time", "CA"),
    "America/Rio_Branco": ("SA Pacific Standard Time", "BR"),
    "America/Santa_Isabel": ("Pacific Standard Time (Mexico)", "MX"),
    "America/Santarem": ("SA Eastern Standard Time", "BR"),
    "America/Santiago": ("Pacific SA Standard Time", "001"),
    "America/Santo_Domingo": ("SA Western Standard Time", "DO"),
    "America/Sao_Paulo": ("E. South America Standard Time", "001"),
    "America/Scoresbysund": ("Azores Standard Time", "GL"),
    "America/Sitka": ("Alaskan Standard Time", "US"),
    "America/St_Barthelemy": ("SA Western Standard Time", "BL"),
    "America/St_Johns": ("Newfoundland Standard Time", "001"),
    "America/St_Kitts": ("SA Western Standard Time", "KN"),
    "America/St_Lucia": ("SA Western Standard Time", "LC"),
    "America/St_Thomas": ("SA Western Standard Time", "VI"),
    "America/St_Vincent": ("SA Western Standard Time", "VC"),
    "America/Swift_Current": ("Canada Central Standard Time", "CA"),
    "America/Tegucigalpa": ("Central America Standard Time", "HN"),
    "America/Thule": ("Atlantic Standard Time", "GL"),
    "America/Thunder_Bay": ("Eastern Standard Time", "CA"),
    "America/Tijuana": ("Pacific Standard Time (Mexico)", "001"),
    "America/Toronto": ("Eastern Standard Time", "CA"),
    "America/Tortola": ("SA Western Standard Time", "VG"),
    "America/Vancouver": ("Pacific Standard Time", "CA"),
    "America/Whitehorse": ("Yukon Standard Time", "001"),
    "America/Winnipeg": ("Central Standard Time", "CA"),
    "America/Yakutat": ("Alaskan Standard Time", "US"),
    "America/Yellowknife": ("Mountain Standard Time", "CA"),
    "Antarctica/Casey": ("Central Pacific Standard Time", "AQ"),
    "Antarctica/Davis": ("SE Asia Standard Time", "AQ"),
    "Antarctica/DumontDUrville": ("West Pacific Standard Time", "AQ"),
    "Antarctica/Macquarie": ("Tasmania Standard Time", "AU"),
    "Antarctica/Mawson": ("West Asia Standard Time", "AQ"),
    "Antarctica/McMurdo": ("New Zealand Standard Time", "AQ"),
    "Antarctica/Palmer": ("SA Eastern Standard Time", "AQ"),
    "Antarctica/Rothera": ("SA Eastern Standard Time", "AQ"),
    "Antarctica/Syowa": ("E. Africa Standard Time", "AQ"),
    "Antarctica/Vostok": ("Central Asia Standard Time", "AQ"),
    "Arctic/Longyearbyen": ("W. Europe Standard Time", "SJ"),
    "Asia/Aden": ("Arab Standard Time", "YE"),
    "Asia/Almaty": ("Central Asia Standard Time", "001"),
    "Asia/Amman": ("Jordan Standard Time", "001"),
    "Asia/Anadyr": ("Russia Time Zone 11", "RU"),
    "Asia/Aqtau": ("West Asia Standard Time", "KZ"),
    "Asia/Aqtobe": ("West Asia Standard Time", "KZ"),
    "Asia/Ashgabat": ("West Asia Standard Time", "TM"),
    "Asia/Atyrau": ("West Asia Standard Time", "KZ"),
    "Asia/Baghdad": ("Arabic Standard Time", "001"),
    "Asia/Bahrain": ("Arab Standard Time", "BH"),
    "Asia/Baku": ("Azerbaijan Standard Time", "001"),
    "Asia/Bangkok": ("SE Asia Standard Time", "001"),
    "Asia/Barnaul": ("Altai Standard Time", "001"),
    "Asia/Beirut": ("Middle East Standard Time", "001"),
    "Asia/Bishkek": ("Central Asia Standard Time", "KG"),
    "Asia/Brunei": ("Singapore Standard Time", "BN"),
    "Asia/Calcutta": ("India Standard Time", "001"),
    "Asia/Chita": ("Transbaikal Standard Time", "001"),
    "Asia/Choibalsan": ("Ulaanbaatar Standard Time", "MN"),
    "Asia/Colombo": ("Sri Lanka Standard Time", "001"),
    "Asia/Damascus": ("Syria Standard Time", "001"),
    "Asia/Dhaka": ("Bangladesh Standard Time", "001"),
    "Asia/Dili": ("Tokyo Standard Time", "TL"),
    "Asia/Dubai": ("Arabian Standard Time", "001"),
    "Asia/Dushanbe": ("West Asia Standard Time", "TJ"),
    "Asia/Famagusta": ("GTB Standard Time", "CY"),
    "Asia/Gaza": ("West Bank Standard Time", "PS"),
    "Asia/Hebron": ("West Bank Standard Time", "001"),
    "Asia/Hong_Kong": ("China Standard Time", "HK"),
    "Asia/Hovd": ("W. Mongolia Standard Time", "001"),
    "Asia/Irkutsk": ("North Asia East Standard Time", "001"),
    "Asia/Jakarta": ("SE Asia Standard Time", "ID"),
    "Asia/Jayapura": ("Tokyo Standard Time", "ID"),
    "Asia/Jerusalem": ("Israel Standard Time", "001"),
    "Asia/Kabul": ("Afghanistan Standard Time", "001"),
    "Asia/Kamchatka": ("Russia Time Zone 11", "001"),
    "Asia/Karachi": ("Pakistan Standard Time", "001"),
    "Asia/Katmandu": ("Nepal Standard Time", "001"),
    "Asia/Khandyga": ("Yakutsk Standard Time", "RU"),
    "Asia/Krasnoyarsk": ("North Asia Standard Time", "001"),
    "Asia/Kuala_Lumpur": ("Singapore Standard Time", "MY"),
    "Asia/Kuching": ("Singapore Standard Time", "MY"),