import ctypes
import gettext
import locale
import os
import re
import subprocess
import sys
from typing import Optional

from clarabot_nano.resource import get_resource_path


def get_system_language() -> Optional[str]:
    """
    There is a huge mess with locales in general, they are not reliable for detecting the language of the OS.
    """
    sys_lang = None
    if sys.platform.startswith("win"):
        language = locale.windows_locale.get(ctypes.windll.kernel32.GetUserDefaultUILanguage())
        if language:
            sys_lang = language.partition("_")[0]
    elif sys.platform.startswith("darwin"):
        try:  # works from MacOS 10.4 approx.
            languages = subprocess.check_output(["defaults", "read", ".GlobalPreferences", "AppleLanguages"])
        except subprocess.CalledProcessError:
            pass  # TODO log warning
        else:
            languages = languages.decode("utf-8", errors="replace").strip("()")
            languages = re.sub(r"[\s]", "", languages)
            languages = [l.strip('"') for l in languages.split(",")]
            languages = [l for l in languages if l]
            if isinstance(languages, list) and languages and isinstance(languages[0], str):
                sys_lang = languages[0].partition("-")[0]
    else:  # Should work on most POSIX systems. (based on gettext)
        for key in ("LANGUAGE", "LC_ALL", "LC_MESSAGES", "LANG"):
            languages = os.environ.get(key)
            if languages:
                languages = languages.split(":")
                if languages and languages[0]:
                    sys_lang = languages[0].partition("_")[0]
                    break

    if sys_lang:  # coerce accidental empty string
        return sys_lang.lower()


I18N_DOMAIN = "clarabot-nano"
L10N_FOLDER = str(get_resource_path("locale"))
DETECTED_SYSTEM_LANGUAGE = get_system_language()
DEFAULT_L10N = gettext.translation(
    I18N_DOMAIN, L10N_FOLDER, [DETECTED_SYSTEM_LANGUAGE] if DETECTED_SYSTEM_LANGUAGE else None, fallback=True
)
EFFECTIVE_LANGUAGE = DEFAULT_L10N.info().get("language", "en")


def install_default_l10n():
    DEFAULT_L10N.install(names=["gettext", "ngettext"])
