#
# Copyright 2007-2011 Zuza Software Foundation
#
# This file is part of translate.
#
# translate is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# translate is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.

"""This module stores information and functionality that relates to plurals."""

import re
import unicodedata

languages = {
    "ach": ("Acholi", 2, "n > 1"),
    "af": ("Afrikaans", 2, "(n != 1)"),
    "ak": ("Akan", 2, "n > 1"),
    "am": ("Amharic", 2, "n > 1"),
    "an": ("Aragonese", 2, "(n != 1)"),
    "anp": ("Angika", 2, "(n != 1)"),
    "ar": (
        "Arabic",
        6,
        "n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5",
    ),
    "arn": ("Mapudungun; Mapuche", 2, "n > 1"),
    "as": ("Assamese", 2, "(n != 1)"),
    "ast": ("Asturian; Bable; Leonese; Asturleonese", 2, "(n != 1)"),
    "ay": ("Aymará", 1, "0"),
    "az": ("Azerbaijani", 2, "(n != 1)"),
    "be": (
        "Belarusian",
        3,
        "n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2",
    ),
    "bg": ("Bulgarian", 2, "(n != 1)"),
    "bn": ("Bengali", 2, "(n != 1)"),
    "bn_BD": ("Bengali (Bangladesh)", 2, "(n != 1)"),
    "bn_IN": ("Bengali (India)", 2, "(n != 1)"),
    "bo": ("Tibetan", 1, "0"),
    "br": ("Breton", 2, "n > 1"),
    "brx": ("Bodo", 2, "(n != 1)"),
    "bs": (
        "Bosnian",
        3,
        "n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2",
    ),
    "ca": ("Catalan; Valencian", 2, "(n != 1)"),
    "ca@valencia": ("Catalan; Valencian (Valencia)", 2, "(n != 1)"),
    "cgg": ("Chiga", 1, "0"),
    "cs": ("Czech", 3, "(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2"),
    "csb": (
        "Kashubian",
        3,
        "n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2",
    ),
    "cy": ("Welsh", 2, "(n==2) ? 1 : 0"),
    "da": ("Danish", 2, "(n != 1)"),
    "de": ("German", 2, "(n != 1)"),
    "doi": ("Dogri", 2, "(n != 1)"),
    "dz": ("Dzongkha", 1, "0"),
    "el": ("Greek, Modern (1453-)", 2, "(n != 1)"),
    "en": ("English", 2, "(n != 1)"),
    "en_GB": ("English (United Kingdom)", 2, "(n != 1)"),
    "en_ZA": ("English (South Africa)", 2, "(n != 1)"),
    "eo": ("Esperanto", 2, "(n != 1)"),
    "es": ("Spanish; Castilian", 2, "(n != 1)"),
    "es_AR": ("Argentinean Spanish", 2, "(n != 1)"),
    "et": ("Estonian", 2, "(n != 1)"),
    "eu": ("Basque", 2, "(n != 1)"),
    "fa": ("Persian", 2, "n > 1"),
    "ff": ("Fulah", 2, "(n != 1)"),
    "fi": ("Finnish", 2, "(n != 1)"),
    "fil": ("Filipino; Pilipino", 2, "(n > 1)"),
    "fo": ("Faroese", 2, "(n != 1)"),
    "fr": ("French", 2, "(n > 1)"),
    "fur": ("Friulian", 2, "(n != 1)"),
    "fy": ("Frisian", 2, "(n != 1)"),
    "ga": ("Irish", 5, "n==1 ? 0 : n==2 ? 1 : (n>2 && n<7) ? 2 :(n>6 && n<11) ? 3 : 4"),
    "gd": (
        "Gaelic; Scottish Gaelic",
        4,
        "(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3",
    ),
    "gl": ("Galician", 2, "(n != 1)"),
    "gu": ("Gujarati", 2, "(n != 1)"),
    "gun": ("Gun", 2, "(n > 1)"),
    "ha": ("Hausa", 2, "(n != 1)"),
    "he": ("Hebrew", 2, "(n != 1)"),
    "hi": ("Hindi", 2, "(n != 1)"),
    "hne": ("Chhattisgarhi", 2, "(n != 1)"),
    "hr": (
        "Croatian",
        3,
        "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)",
    ),
    "ht": ("Haitian; Haitian Creole", 2, "(n != 1)"),
    "hu": ("Hungarian", 2, "(n != 1)"),
    "hy": ("Armenian", 1, "0"),
    "ia": ("Interlingua (International Auxiliary Language Association)", 2, "(n != 1)"),
    "id": ("Indonesian", 1, "0"),
    "is": ("Icelandic", 2, "(n != 1)"),
    "it": ("Italian", 2, "(n != 1)"),
    "ja": ("Japanese", 1, "0"),
    "jbo": ("Lojban", 1, "0"),
    "jv": ("Javanese", 2, "(n != 1)"),
    "ka": ("Georgian", 1, "0"),
    "kab": ("Kabyle", 2, "(n != 1)"),
    "kk": ("Kazakh", 2, "n != 1"),
    "kl": ("Greenlandic", 2, "(n != 1)"),
    "km": ("Central Khmer", 1, "0"),
    "kn": ("Kannada", 2, "(n != 1)"),
    "ko": ("Korean", 1, "0"),
    "kok": ("Konkani", 2, "(n != 1)"),
    "ks": ("Kashmiri", 2, "(n != 1)"),
    "ku": ("Kurdish", 2, "(n != 1)"),
    "kw": ("Cornish", 4, "(n==1) ? 0 : (n==2) ? 1 : (n == 3) ? 2 : 3"),
    "ky": ("Kirghiz; Kyrgyz", 2, "n != 1"),
    "lb": ("Luxembourgish; Letzeburgesch", 2, "(n != 1)"),
    "ln": ("Lingala", 2, "(n > 1)"),
    "lo": ("Lao", 1, "0"),
    "lt": (
        "Lithuanian",
        3,
        "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2)",
    ),
    "lv": ("Latvian", 3, "(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)"),
    "mai": ("Maithili", 2, "(n != 1)"),
    "me": (
        "Montenegrin",
        3,
        "n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2",
    ),
    "mfe": ("Morisyen", 2, "(n > 1)"),
    "mg": ("Malagasy", 2, "(n > 1)"),
    "mi": ("Maori", 2, "(n > 1)"),
    "mk": ("Macedonian", 2, "(n==1 || n%10==1 ? 0 : 1)"),
    "ml": ("Malayalam", 2, "(n != 1)"),
    "mn": ("Mongolian", 2, "(n != 1)"),
    "mni": ("Meithei (Manipuri)", 2, "(n != 1)"),
    "mnk": ("Mandinka", 3, "(n==0 ? 0 : n==1 ? 1 : 2)"),
    "mr": ("Marathi", 2, "(n != 1)"),
    "ms": ("Malay", 1, "0"),
    "mt": (
        "Maltese",
        4,
        "(n==1 ? 0 : n==0 || ( n%100>1 && n%100<11) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3)",
    ),
    "my": ("Burmese", 1, "0"),
    "nah": ("Nahuatl languages", 2, "(n != 1)"),
    "nap": ("Neapolitan", 2, "(n != 1)"),
    "nb": ("Bokmål, Norwegian; Norwegian Bokmål", 2, "(n != 1)"),
    "ne": ("Nepali", 2, "(n != 1)"),
    "nl": ("Dutch; Flemish", 2, "(n != 1)"),
    "nn": ("Norwegian Nynorsk; Nynorsk, Norwegian", 2, "(n != 1)"),
    "nqo": ("N'Ko", 2, "(n > 1)"),
    "nso": ("Pedi; Sepedi; Northern Sotho", 2, "(n != 1)"),
    "oc": ("Occitan (post 1500)", 2, "(n > 1)"),
    "or": ("Odia", 2, "(n != 1)"),
    "pa": ("Panjabi; Punjabi", 2, "(n != 1)"),
    "pap": ("Papiamento", 2, "(n != 1)"),
    "pl": (
        "Polish",
        3,
        "(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)",
    ),
    "pms": ("Piemontese", 2, "(n != 1)"),
    "ps": ("Pushto; Pashto", 2, "(n != 1)"),
    "pt": ("Portuguese", 2, "(n != 1)"),
    "pt_BR": ("Portuguese (Brazil)", 2, "(n > 1)"),
    "rm": ("Romansh", 2, "(n != 1)"),
    "ro": ("Romanian", 3, "(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2)"),
    "ru": (
        "Russian",
        3,
        "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)",
    ),
    "rw": ("Kinyarwanda", 2, "(n != 1)"),
    "sa": ("Sanskrit", 3, "(n==1 ? 0 : n==2 ? 1 : 2)"),
    "sah": ("Yakut", 1, "0"),
    "sat": ("Santali", 2, "(n != 1)"),
    "sco": ("Scots", 2, "(n != 1)"),
    "scn": ("Sicilian", 2, "(n != 1)"),
    "sd": ("Sindhi", 2, "(n != 1)"),
    "se": ("Northern Sami", 2, "(n != 1)"),
    "si": ("Sinhala; Sinhalese", 2, "(n != 1)"),
    "sk": ("Slovak", 3, "(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2"),
    "sl": (
        "Slovenian",
        4,
        "(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3)",
    ),
    "so": ("Somali", 2, "(n != 1)"),
    "son": ("Songhai languages", 1, "0"),
    "sq": ("Albanian", 2, "(n != 1)"),
    "sr": (
        "Serbian",
        3,
        "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)",
    ),
    "st": ("Sotho, Southern", 2, "(n != 1)"),
    "su": ("Sundanese", 1, "0"),
    "sv": ("Swedish", 2, "(n != 1)"),
    "sw": ("Swahili", 2, "(n != 1)"),
    "szl": (
        "Silesian",
        3,
        "(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)",
    ),
    "ta": ("Tamil", 2, "(n != 1)"),
    "te": ("Telugu", 2, "(n != 1)"),
    "tg": ("Tajik", 1, "0"),
    "th": ("Thai", 1, "0"),
    "ti": ("Tigrinya", 2, "(n > 1)"),
    "tk": ("Turkmen", 2, "(n != 1)"),
    "tr": ("Turkish", 2, "(n != 1)"),
    "tt": ("Tatar", 1, "0"),
    "ug": ("Uighur; Uyghur", 1, "0"),
    "uk": (
        "Ukrainian",
        3,
        "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)",
    ),
    "ur": ("Urdu", 2, "(n != 1)"),
    "uz": ("Uzbek", 2, "(n > 1)"),
    "ve": ("Venda", 2, "(n != 1)"),
    "vi": ("Vietnamese", 1, "0"),
    "wa": ("Walloon", 2, "(n > 1)"),
    "wo": ("Wolof", 2, "(n != 1)"),
    "yo": ("Yoruba", 2, "(n != 1)"),
    "yue": ("Yue", 1, "0"),
    # Chinese is difficult because the main divide is on script, not really
    # country. Simplified Chinese is used mostly in China, Singapore and Malaysia.
    # Traditional Chinese is used mostly in Hong Kong, Taiwan and Macau.
    "zh_CN": ("Chinese (China)", 1, "0"),
    "zh_HK": ("Chinese (Hong Kong)", 1, "0"),
    "zh_TW": ("Chinese (Taiwan)", 1, "0"),
    "zu": ("Zulu", 2, "(n != 1)"),
}
"""Dictionary of language data.
The language code is the dictionary key (which may contain country codes
and modifiers).  The value is a tuple: (Full name in English from iso-codes,
nplurals, plural equation).

Note that the English names should not be used in user facing places - it
should always be passed through the function returned from tr_lang(), or at
least passed through _fix_language_name()."""

_fixed_names = {
    "Asturian; Bable; Leonese; Asturleonese": "Asturian",
    "Bokmål, Norwegian; Norwegian Bokmål": "Norwegian Bokmål",
    "Catalan; Valencian": "Catalan",
    "Central Khmer": "Khmer",
    "Chichewa; Chewa; Nyanja": "Chewa; Nyanja",
    "Divehi; Dhivehi; Maldivian": "Divehi",
    "Dutch; Flemish": "Dutch",
    "Filipino; Pilipino": "Filipino",
    "Gaelic; Scottish Gaelic": "Scottish Gaelic",
    "Greek, Modern (1453-)": "Greek",
    "Interlingua (International Auxiliary Language Association)": "Interlingua",
    "Kirghiz; Kyrgyz": "Kirghiz",
    "Klingon; tlhIngan-Hol": "Klingon",
    "Limburgan; Limburger; Limburgish": "Limburgish",
    "Low German; Low Saxon; German, Low; Saxon, Low": "Low German",
    "Luxembourgish; Letzeburgesch": "Luxembourgish",
    "Ndebele, South; South Ndebele": "Southern Ndebele",
    "Norwegian Nynorsk; Nynorsk, Norwegian": "Norwegian Nynorsk",
    "Occitan (post 1500)": "Occitan",
    "Panjabi; Punjabi": "Punjabi",
    "Pedi; Sepedi; Northern Sotho": "Northern Sotho",
    "Pushto; Pashto": "Pashto",
    "Sinhala; Sinhalese": "Sinhala",
    "Songhai languages": "Songhay",
    "Sotho, Southern": "Sotho",
    "Spanish; Castilian": "Spanish",
    "Uighur; Uyghur": "Uyghur",
}


scripts = {
    # Codes pulled from http://unicode.org/iso15924/iso15924-codes.html
    # Scripts were figured out from the languages's Wikipedia pages and the
    # real usage in https://mozilla.locamotion.org/
    "Deva": [
        "anp",  # https://en.wikipedia.org/wiki/Angika_language
        "bho",  # https://en.wikipedia.org/wiki/Bhojpuri_language
        "brx",  # https://en.wikipedia.org/wiki/Bodo_language
        "doi",  # https://en.wikipedia.org/wiki/Dogri_language
        "hi",  # https://en.wikipedia.org/wiki/Hindi
        "kfy",  # https://en.wikipedia.org/wiki/Kumaoni_language
        "kok",  # https://en.wikipedia.org/wiki/Konkani_language
        "mai",  # https://en.wikipedia.org/wiki/Maithili_language
        "mr",  # https://en.wikipedia.org/wiki/Marathi_language
        "sa",  # https://en.wikipedia.org/wiki/Sanskrit
        "sat",  # https://en.wikipedia.org/wiki/Santali_language
    ],
    "Beng": [
        "bn",  # https://en.wikipedia.org/wiki/Bengali_language
        "mni",  # https://en.wikipedia.org/wiki/Manipuri_language
    ],
    "Tibt": [
        "bo",  # https://en.wikipedia.org/wiki/Standard_Tibetan
    ],
    "Orya": [
        "or",  # https://en.wikipedia.org/wiki/Odia_language
    ],
    "Gujr": [
        "gu",  # https://en.wikipedia.org/wiki/Gujarati_language
    ],
    "Khmr": [
        "km",  # https://en.wikipedia.org/wiki/Khmer_language
    ],
    "Knda": [
        "kn",  # https://en.wikipedia.org/wiki/Kannada
    ],
    "Laoo": [
        "lo",  # https://en.wikipedia.org/wiki/Lao_language
    ],
    "Mlym": [
        "ml",  # https://en.wikipedia.org/wiki/Malayalam
    ],
    "Mymr": [
        "my",  # https://en.wikipedia.org/wiki/Burmese_language
        "shn",  # https://en.wikipedia.org/wiki/Shan_language
    ],
    "Sind": [
        "sd",  # https://en.wikipedia.org/wiki/Sindhi_language
    ],
    "Taml": [
        "ta",  # https://en.wikipedia.org/wiki/Tamil_language
    ],
    # Unable to find the codes for the following scripts.
    "assamese": [
        "as",  # https://en.wikipedia.org/wiki/Assamese_language
    ],
    "perso-arabic": [
        "ks",  # https://en.wikipedia.org/wiki/Kashmiri_language
    ],
    "chinese": [
        "yue",  # https://en.wikipedia.org/wiki/Yue_Chinese
    ],
}
"""Dictionary of scripts data.
The dictionary keys are ISO 15924 script codes, and script names where scripts
are missing from standard. The value is a list of codes for languages using
that script.

This is mainly used to alter the behavior of some checks (the accelerators one
for example)."""


cldr_plural_categories = [
    "zero",
    "one",
    "two",
    "few",
    "many",
    "other",
]

"""List of plural tags generated from CLDR 44.0.1 using
https://github.com/WeblateOrg/language-data
"""
plural_tags = {
    "adp": ["other"],
    "af": ["one", "other"],
    "afr": ["one", "other"],
    "ak": ["one", "other"],
    "aka": ["one", "other"],
    "alb": ["one", "other"],
    "als": ["one", "other"],
    "am": ["one", "other"],
    "amh": ["one", "other"],
    "an": ["one", "other"],
    "ar": ["zero", "one", "two", "few", "many", "other"],
    "ara": ["zero", "one", "two", "few", "many", "other"],
    "arb": ["zero", "one", "two", "few", "many", "other"],
    "arg": ["one", "other"],
    "arm": ["one", "other"],
    "ars": ["zero", "one", "two", "few", "many", "other"],
    "ary": ["zero", "one", "two", "few", "many", "other"],
    "as": ["one", "other"],
    "asa": ["one", "other"],
    "asm": ["one", "other"],
    "ast": ["one", "other"],
    "az": ["one", "other"],
    "aze": ["one", "other"],
    "azj": ["one", "other"],
    "bal": ["one", "other"],
    "bam": ["other"],
    "baq": ["one", "other"],
    "base": ["one", "other"],
    "bcc": ["one", "other"],
    "bd": ["one", "other"],
    "be": ["one", "few", "many"],
    "be@latin": ["one", "few", "many"],
    "bel": ["one", "few", "many"],
    "bem": ["one", "other"],
    "ben": ["one", "other"],
    "bez": ["one", "other"],
    "bg": ["one", "other"],
    "bgr": ["one", "other"],
    "bh": ["one", "other"],
    "bho": ["one", "other"],
    "bih": ["one", "other"],
    "blo": ["zero", "one", "other"],
    "bm": ["other"],
    "bn": ["one", "other"],
    "bo": ["other"],
    "bod": ["other"],
    "bos": ["one", "few", "other"],
    "bp": ["one", "many", "other"],
    "br": ["one", "two", "few", "many", "other"],
    "braz_por": ["one", "many", "other"],
    "bre": ["one", "two", "few", "many", "other"],
    "brx": ["one", "other"],
    "bs": ["one", "few", "other"],
    "bul": ["one", "other"],
    "bur": ["other"],
    "by": ["one", "few", "many"],
    "ca": ["one", "many", "other"],
    "cat": ["one", "many", "other"],
    "ce": ["one", "other"],
    "ceb": ["one", "other"],
    "ces": ["one", "few", "other"],
    "cgg": ["one", "other"],
    "che": ["one", "other"],
    "chi": ["other"],
    "chinese": ["other"],
    "chr": ["one", "other"],
    "chs": ["other"],
    "cht": ["other"],
    "ckb": ["one", "other"],
    "cld": ["one", "other"],
    "cmn": ["other"],
    "cn": ["other"],
    "cnr": ["one", "few", "other"],
    "cor": ["zero", "one", "two", "few", "many", "other"],
    "cs": ["one", "few", "other"],
    "csy": ["one", "few", "other"],
    "cy": ["zero", "one", "two", "few", "many", "other"],
    "cym": ["zero", "one", "two", "few", "many", "other"],
    "cz": ["one", "few", "other"],
    "cze": ["one", "few", "other"],
    "da": ["one", "other"],
    "dan": ["one", "other"],
    "de": ["one", "other"],
    "des": ["one", "other"],
    "deu": ["one", "other"],
    "dgo": ["one", "other"],
    "div": ["one", "other"],
    "dk": ["one", "other"],
    "doi": ["one", "other"],
    "drh": ["one", "other"],
    "drw": ["one", "other"],
    "dsb": ["one", "two", "few", "other"],
    "dut": ["one", "other"],
    "dutch_be": ["one", "other"],
    "dv": ["one", "other"],
    "dz": ["other"],
    "dzo": ["other"],
    "ee": ["one", "other"],
    "eg": ["zero", "one", "two", "few", "many", "other"],
    "ekk": ["one", "other"],
    "el": ["one", "other"],
    "ell": ["one", "other"],
    "en": ["one", "other"],
    "ena": ["one", "other"],
    "eng": ["one", "other"],
    "english_uk": ["one", "other"],
    "enp": ["one", "other"],
    "enu": ["one", "other"],
    "eo": ["one", "other"],
    "epo": ["one", "other"],
    "es": ["one", "many", "other"],
    "es_eu": ["one", "other"],
    "esp": ["one", "many", "other"],
    "est": ["one", "other"],
    "et": ["one", "other"],
    "eu": ["one", "other"],
    "eus": ["one", "other"],
    "ewe": ["one", "other"],
    "fa": ["one", "other"],
    "fao": ["one", "other"],
    "fas": ["one", "other"],
    "fat": ["one", "other"],
    "ff": ["one", "other"],
    "fi": ["one", "other"],
    "fil": ["one", "other"],
    "fin": ["one", "other"],
    "flemish": ["one", "other"],
    "fo": ["one", "other"],
    "fr": ["one", "many", "other"],
    "fra": ["one", "many", "other"],
    "frb": ["one", "many", "other"],
    "fre": ["one", "many", "other"],
    "fry": ["one", "other"],
    "fuc": ["one", "other"],
    "ful": ["one", "other"],
    "fur": ["one", "other"],
    "fy": ["one", "other"],
    "ga": ["one", "two", "few", "many", "other"],
    "gae": ["one", "two", "few", "other"],
    "gaz": ["one", "other"],
    "gd": ["one", "two", "few", "other"],
    "geo": ["one", "other"],
    "ger": ["one", "other"],
    "gl": ["one", "other"],
    "gla": ["one", "two", "few", "other"],
    "gle": ["one", "two", "few", "many", "other"],
    "glg": ["one", "other"],
    "glv": ["one", "two", "few", "other"],
    "gr": ["one", "other"],
    "gre": ["one", "other"],
    "gsw": ["one", "other"],
    "gu": ["one", "other"],
    "guj": ["one", "other"],
    "guw": ["one", "other"],
    "gv": ["one", "two", "few", "other"],
    "ha": ["one", "other"],
    "hau": ["one", "other"],
    "haw": ["one", "other"],
    "hbs": ["one", "few", "other"],
    "he": ["one", "two", "other"],
    "heb": ["one", "two", "other"],
    "hi": ["one", "other"],
    "hin": ["one", "other"],
    "hnj": ["other"],
    "hr": ["one", "few", "other"],
    "hrv": ["one", "few", "other"],
    "hsb": ["one", "two", "few", "other"],
    "hu": ["one", "other"],
    "hun": ["one", "other"],
    "hy": ["one", "other"],
    "hye": ["one", "other"],
    "ia": ["one", "other"],
    "ibo": ["other"],
    "ice": ["one", "other"],
    "id": ["other"],
    "ido": ["one", "other"],
    "ig": ["other"],
    "ii": ["other"],
    "iii": ["other"],
    "ike": ["one", "two", "other"],
    "iku": ["one", "two", "other"],
    "in": ["other"],
    "ina": ["one", "other"],
    "ind": ["other"],
    "io": ["one", "other"],
    "is": ["one", "other"],
    "isl": ["one", "other"],
    "it": ["one", "many", "other"],
    "ita": ["one", "many", "other"],
    "its": ["one", "many", "other"],
    "iu": ["one", "two", "other"],
    "iw": ["one", "two", "other"],
    "ja": ["other"],
    "jav": ["other"],
    "jbo": ["other"],
    "jgo": ["one", "other"],
    "ji": ["one", "other"],
    "jmc": ["one", "other"],
    "jp": ["other"],
    "jpn": ["other"],
    "jv": ["other"],
    "jw": ["other"],
    "ka": ["one", "other"],
    "kab": ["one", "other"],
    "kaj": ["one", "other"],
    "kal": ["one", "other"],
    "kan": ["one", "other"],
    "kas": ["one", "other"],
    "kat": ["one", "other"],
    "kaz": ["one", "other"],
    "kcg": ["one", "other"],
    "kde": ["other"],
    "kea": ["other"],
    "khk": ["one", "other"],
    "khm": ["other"],
    "kir": ["one", "other"],
    "kk": ["one", "other"],
    "kk@latin": ["one", "other"],
    "kkj": ["one", "other"],
    "kl": ["one", "other"],
    "km": ["other"],
    "kmr": ["one", "other"],
    "kn": ["one", "other"],
    "ko": ["other"],
    "kor": ["other"],
    "ks": ["one", "other"],
    "ksb": ["one", "other"],
    "ksh": ["zero", "one", "other"],
    "ku": ["one", "other"],
    "kur": ["one", "other"],
    "kw": ["zero", "one", "two", "few", "many", "other"],
    "ky": ["one", "other"],
    "kz": ["one", "other"],
    "lag": ["zero", "one", "other"],
    "lah": ["one", "other"],
    "lao": ["other"],
    "lav": ["zero", "one", "other"],
    "lb": ["one", "other"],
    "lg": ["one", "other"],
    "lij": ["one", "other"],
    "lin": ["one", "other"],
    "lit": ["one", "few", "other"],
    "lk": ["one", "other"],
    "lkt": ["other"],
    "ln": ["one", "other"],
    "lo": ["other"],
    "lt": ["one", "few", "other"],
    "ltz": ["one", "other"],
    "lug": ["one", "other"],
    "lv": ["zero", "one", "other"],
    "lvs": ["zero", "one", "other"],
    "mac": ["one", "other"],
    "mal": ["one", "other"],
    "mar": ["one", "other"],
    "mas": ["one", "other"],
    "may": ["other"],
    "me": ["one", "few", "other"],
    "mg": ["one", "other"],
    "mgo": ["one", "other"],
    "mk": ["one", "other"],
    "mkd": ["one", "other"],
    "ml": ["one", "other"],
    "mlg": ["one", "other"],
    "mlt": ["one", "two", "few", "many", "other"],
    "mn": ["one", "other"],
    "mo": ["one", "few", "other"],
    "mol": ["one", "few", "other"],
    "mon": ["one", "other"],
    "mr": ["one", "other"],
    "ms": ["other"],
    "msa": ["other"],
    "mspanish": ["one", "many", "other"],
    "mt": ["one", "two", "few", "many", "other"],
    "my": ["other"],
    "mya": ["other"],
    "nah": ["one", "other"],
    "naq": ["one", "two", "other"],
    "nb": ["one", "other"],
    "nbl": ["one", "other"],
    "nd": ["one", "other"],
    "nde": ["one", "other"],
    "ne": ["one", "other"],
    "nep": ["one", "other"],
    "nl": ["one", "other"],
    "nlb": ["one", "other"],
    "nld": ["one", "other"],
    "nn": ["one", "other"],
    "nnh": ["one", "other"],
    "nno": ["one", "other"],
    "no": ["one", "other"],
    "nob": ["one", "other"],
    "nor": ["one", "other"],
    "norwegian": ["one", "other"],
    "np": ["one", "other"],
    "npi": ["one", "other"],
    "nqo": ["other"],
    "nr": ["one", "other"],
    "nso": ["one", "other"],
    "ny": ["one", "other"],
    "nya": ["one", "other"],
    "nyn": ["one", "other"],
    "om": ["one", "other"],
    "or": ["one", "other"],
    "ori": ["one", "other"],
    "orm": ["one", "other"],
    "ory": ["one", "other"],
    "os": ["one", "other"],
    "osa": ["other"],
    "oss": ["one", "other"],
    "pa": ["one", "other"],
    "pan": ["one", "other"],
    "pap": ["one", "other"],
    "pbu": ["one", "other"],
    "pcm": ["one", "other"],
    "per": ["one", "other"],
    "pes": ["one", "other"],
    "pk": ["one", "other"],
    "pl": ["one", "few", "many"],
    "plk": ["one", "few", "many"],
    "plt": ["one", "other"],
    "pnb": ["one", "other"],
    "pol": ["one", "few", "many"],
    "por": ["one", "many", "other"],
    "portuguese_br": ["one", "many", "other"],
    "portuguese_portugal": ["one", "many", "other"],
    "prg": ["zero", "one", "other"],
    "prs": ["one", "other"],
    "ps": ["one", "other"],
    "pt": ["one", "many", "other"],
    "pt_PT": ["one", "many", "other"],
    "ptb": ["one", "many", "other"],
    "ptg": ["one", "many", "other"],
    "pu": ["one", "other"],
    "pus": ["one", "other"],
    "rm": ["one", "other"],
    "ro": ["one", "few", "other"],
    "rof": ["one", "other"],
    "roh": ["one", "other"],
    "ron": ["one", "few", "other"],
    "rs": ["one", "few", "other"],
    "ru": ["one", "few", "many"],
    "rum": ["one", "few", "other"],
    "rus": ["one", "few", "many"],
    "rwk": ["one", "other"],
    "sag": ["other"],
    "sah": ["other"],
    "saq": ["one", "other"],
    "sat": ["one", "two", "other"],
    "sc": ["one", "other"],
    "scc": ["one", "few", "other"],
    "schinese": ["other"],
    "scn": ["one", "other"],
    "scr": ["one", "few", "other"],
    "sd": ["one", "other"],
    "sdh": ["one", "other"],
    "se": ["one", "two", "other"],
    "seh": ["one", "other"],
    "serbo_croatian": ["one", "few", "other"],
    "ses": ["other"],
    "sg": ["other"],
    "sh": ["one", "few", "other"],
    "shi": ["one", "few", "other"],
    "si": ["one", "other"],
    "sin": ["one", "other"],
    "sk": ["one", "few", "other"],
    "sky": ["one", "few", "other"],
    "sl": ["one", "two", "few", "other"],
    "slk": ["one", "few", "other"],
    "slo": ["one", "few", "other"],
    "slv": ["one", "two", "few", "other"],
    "sma": ["one", "two", "other"],
    "sme": ["one", "two", "other"],
    "smi": ["one", "two", "other"],
    "smj": ["one", "two", "other"],
    "smn": ["one", "two", "other"],
    "sms": ["one", "two", "other"],
    "sn": ["one", "other"],
    "sna": ["one", "other"],
    "snd": ["one", "other"],
    "so": ["one", "other"],
    "som": ["one", "other"],
    "sot": ["one", "other"],
    "source": ["one", "other"],
    "spa": ["one", "many", "other"],
    "sq": ["one", "other"],
    "sqi": ["one", "other"],
    "sr": ["one", "few", "other"],
    "sr@cyrillic": ["one", "few", "other"],
    "sr@latin": ["one", "few", "other"],
    "srb": ["one", "few", "other"],
    "src": ["one", "other"],
    "srd": ["one", "other"],
    "srl": ["one", "few", "other"],
    "srp": ["one", "few", "other"],
    "ss": ["one", "other"],
    "ssw": ["one", "other"],
    "ssy": ["one", "other"],
    "st": ["one", "other"],
    "su": ["other"],
    "sun": ["other"],
    "sv": ["one", "other"],
    "sve": ["one", "other"],
    "svk": ["one", "few", "other"],
    "sw": ["one", "other"],
    "swa": ["one", "other"],
    "swc": ["one", "other"],
    "swe": ["one", "other"],
    "swh": ["one", "other"],
    "syr": ["one", "other"],
    "ta": ["one", "other"],
    "tam": ["one", "other"],
    "tchinese": ["other"],
    "te": ["one", "other"],
    "tel": ["one", "other"],
    "teo": ["one", "other"],
    "tgl": ["one", "other"],
    "th": ["other"],
    "tha": ["other"],
    "ti": ["one", "other"],
    "tib": ["other"],
    "tig": ["one", "other"],
    "tir": ["one", "other"],
    "tk": ["one", "other"],
    "tl": ["one", "other"],
    "tn": ["one", "other"],
    "tnf": ["one", "other"],
    "to": ["other"],
    "ton": ["other"],
    "tpi": ["other"],
    "tr": ["one", "other"],
    "trk": ["one", "other"],
    "ts": ["one", "other"],
    "tsn": ["one", "other"],
    "tso": ["one", "other"],
    "tuk": ["one", "other"],
    "tur": ["one", "other"],
    "tw": ["one", "other"],
    "twi": ["one", "other"],
    "tzm": ["one", "other"],
    "ua": ["one", "few", "many"],
    "ug": ["one", "other"],
    "uig": ["one", "other"],
    "uk": ["one", "few", "many"],
    "ukr": ["one", "few", "many"],
    "und": ["other"],
    "ur": ["one", "other"],
    "urd": ["one", "other"],
    "us": ["one", "other"],
    "uz": ["one", "other"],
    "uz@cyrillic": ["one", "other"],
    "uz@latin": ["one", "other"],
    "uz@latn": ["one", "other"],
    "uzb": ["one", "other"],
    "uzn": ["one", "other"],
    "ve": ["one", "other"],
    "vec": ["one", "many", "other"],
    "ven": ["one", "other"],
    "vi": ["other"],
    "vie": ["other"],
    "vn": ["other"],
    "vo": ["one", "other"],
    "vol": ["one", "other"],
    "vun": ["one", "other"],
    "wa": ["one", "other"],
    "wae": ["one", "other"],
    "wel": ["zero", "one", "two", "few", "many", "other"],
    "wln": ["one", "other"],
    "wo": ["other"],
    "wol": ["other"],
    "xbelorussian": ["one", "few", "many"],
    "xh": ["one", "other"],
    "xho": ["one", "other"],
    "xog": ["one", "other"],
    "ydd": ["one", "other"],
    "yi": ["one", "other"],
    "yid": ["one", "other"],
    "yo": ["other"],
    "yor": ["other"],
    "yue": ["other"],
    "zh": ["other"],
    "zhcn": ["other"],
    "zho": ["other"],
    "zhtw": ["other"],
    "zsm": ["other"],
    "zu": ["one", "other"],
    "zul": ["one", "other"],
}

# Qt Linguist plural tags, extracted from
# https://github.com/WeblateOrg/language-data
qt_plural_tags = {
    "aa": ["one", "other"],
    "ab": ["one", "other"],
    "af": ["one", "other"],
    "am": ["one", "other"],
    "ar": ["zero", "one", "two", "few", "many", "other"],
    "as": ["one", "other"],
    "ay": ["one", "other"],
    "az": ["one", "other"],
    "ba": ["one", "other"],
    "be": ["one", "few", "many"],
    "bg": ["one", "other"],
    "bi": ["other"],
    "bn": ["one", "other"],
    "bo": ["other"],
    "br": ["one", "other"],
    "bs": ["one", "few", "many"],
    "ca": ["one", "other"],
    "co": ["one", "other"],
    "cs": ["one", "few", "many"],
    "cy": ["zero", "one", "few", "many", "other"],
    "da": ["one", "other"],
    "de": ["one", "other"],
    "dv": ["one", "two", "other"],
    "dz": ["other"],
    "el": ["one", "other"],
    "en": ["one", "other"],
    "eo": ["one", "other"],
    "es": ["one", "other"],
    "et": ["one", "other"],
    "eu": ["one", "other"],
    "fa": ["other"],
    "fi": ["one", "other"],
    "fil": ["zero", "one", "other"],
    "fj": ["other"],
    "fo": ["one", "other"],
    "fr": ["one", "other"],
    "fur": ["one", "other"],
    "fy": ["one", "other"],
    "ga": ["one", "two", "other"],
    "gd": ["one", "two", "few", "other"],
    "gl": ["one", "other"],
    "gn": ["other"],
    "gu": ["one", "other"],
    "gv": ["one", "two", "other"],
    "ha": ["one", "other"],
    "he": ["one", "other"],
    "hi": ["one", "other"],
    "hr": ["one", "few", "many"],
    "hu": ["other"],
    "hy": ["one", "other"],
    "ia": ["one", "other"],
    "id": ["other"],
    "ik": ["one", "two", "other"],
    "is": ["one", "other"],
    "it": ["one", "other"],
    "iu": ["one", "two", "other"],
    "ja": ["other"],
    "jv": ["other"],
    "ka": ["one", "other"],
    "kk": ["one", "other"],
    "kl": ["one", "other"],
    "km": ["one", "other"],
    "kn": ["one", "other"],
    "ko": ["other"],
    "ks": ["one", "other"],
    "ku": ["one", "other"],
    "kw": ["one", "other"],
    "ky": ["one", "other"],
    "la": ["one", "other"],
    "lb": ["one", "other"],
    "ln": ["one", "other"],
    "lo": ["one", "other"],
    "lt": ["one", "few", "many"],
    "lv": ["one", "other", "zero"],
    "mg": ["one", "other"],
    "mi": ["one", "two", "other"],
    "mk": ["one", "two", "other"],
    "ml": ["one", "other"],
    "mn": ["one", "other"],
    "mr": ["one", "other"],
    "ms": ["other"],
    "mt": ["one", "zero", "few", "other"],
    "my": ["other"],
    "na": ["other"],
    "nb_NO": ["one", "other"],
    "ne": ["one", "other"],
    "nl": ["one", "other"],
    "nn": ["one", "other"],
    "nso": ["one", "other"],
    "oc": ["one", "other"],
    "om": ["other"],
    "or": ["one", "other"],
    "pa": ["one", "other"],
    "pl": ["one", "few", "many"],
    "ps": ["one", "other"],
    "pt": ["one", "other"],
    "qu": ["one", "other"],
    "rm": ["one", "other"],
    "rn": ["one", "other"],
    "ro": ["one", "few", "other"],
    "ru": ["one", "few", "many"],
    "rw": ["one", "other"],
    "sa": ["one", "two", "other"],
    "sd": ["one", "other"],
    "se": ["one", "two", "other"],
    "si": ["one", "other"],
    "sk": ["one", "few", "many"],
    "sl": ["one", "two", "few", "other"],
    "sm": ["one", "two", "other"],
    "sn": ["one", "other"],
    "so": ["one", "other"],
    "sq": ["one", "other"],
    "sr": ["one", "few", "many"],
    "ss": ["one", "other"],
    "st": ["one", "other"],
    "su": ["other"],
    "sv": ["one", "other"],
    "sw": ["one", "other"],
    "ta": ["one", "other"],
    "te": ["one", "other"],
    "tg": ["one", "other"],
    "th": ["other"],
    "ti": ["one", "other"],
    "tk": ["one", "other"],
    "tn": ["one", "other"],
    "to": ["one", "other"],
    "tr": ["other"],
    "ts": ["one", "other"],
    "tt": ["other"],
    "ug": ["one", "other"],
    "uk": ["one", "few", "many"],
    "ur": ["one", "other"],
    "uz": ["one", "other"],
    "vi": ["other"],
    "vo": ["one", "other"],
    "wa": ["one", "other"],
    "wo": ["one", "other"],
    "xh": ["one", "other"],
    "yi": ["one", "other"],
    "yo": ["other"],
    "za": ["other"],
    "zh": ["other"],
    "zu": ["one", "other"],
}


def simplercode(code):
    """
    This attempts to simplify the given language code by ignoring country
    codes, for example.

    .. seealso::

       - http://www.rfc-editor.org/rfc/bcp/bcp47.txt
       - http://www.rfc-editor.org/rfc/rfc4646.txt
       - http://www.rfc-editor.org/rfc/rfc4647.txt
       - http://www.w3.org/International/articles/language-tags/
    """
    if not code:
        return code
    separator = normalize_code(code).rfind("-")
    if separator >= 0:
        return code[:separator]
    return ""


expansion_factors = {
    "af": 0.1,
    "ar": -0.09,
    "es": 0.21,
    "fr": 0.28,
    "it": 0.2,
}
"""Source to target string length expansion factors."""

langcode_re = re.compile("^[a-z]{2,3}([_-][A-Z]{2,3}|)(@[a-zA-Z0-9]+|)$")
langcode_ire = re.compile("^[a-z]{2,3}([_-][a-z]{2,3})?(@[a-z0-9]+)?$", re.IGNORECASE)
variant_re = re.compile("^[_-][A-Z]{2,3}(@[a-zA-Z0-9]+|)$")


dialect_name_re = re.compile(r"(.+)\s\(([^)\d]{,25})\)$")
# The limit of 25 characters on the country name is so that "Interlingua (...)"
# (see above) is correctly interpreted.


def normalize(string, normal_form="NFC"):
    """
    Return a unicode string in its normalized form.

    :param string: The string to be normalized
    :param normal_form: NFC (default), NFD, NFKC, NFKD
    :return: Normalized string
    """
    if string is None:
        return None
    return unicodedata.normalize(normal_form, string)


def normalize_code(code):
    if not code:
        return code
    return code.replace("_", "-").replace("@", "-").lower()


__normalised_languages = {normalize_code(key) for key in languages}


def simplify_to_common(language_code):
    """
    Simplify language code to the most commonly used form for the language,
    stripping country information for languages that tend not to be localized
    differently for different countries.
    """
    simpler = simplercode(language_code)
    if simpler == "":
        return language_code

    if normalize_code(language_code) in __normalised_languages:
        return language_code

    return simplify_to_common(simpler)


def get_language(code):
    code = code.replace("-", "_").replace("@", "_").lower()
    if "_" in code:
        # convert ab_cd → ab_CD
        code = "{}_{}".format(code.split("_")[0], code.split("_", 1)[1].upper())
    return languages.get(code)
