import textwrap
import os


def single_line_message(message):
    """
    :type message: str | unicode
    :rtype: unicode
    """
    message = message.strip()
    return u" ".join([line.strip() for line in message.split('\n')])


def multi_line_message(message):
    """
    :type message: str | unicode
    :rtype: unicode
    """
    lines = [line for line in message.split('\n')]
    empty_lines = 0
    for i, line in enumerate(lines):
        if line.strip() == '':
            empty_lines = i + 1
        else:
            break
    message = u"\n".join(lines[empty_lines:])
    return textwrap.dedent(message.rstrip())


def multi_line_message_split(message):
    """
    :type message: str | unicode
    :rtype: unicode
    """
    blocks = [block for block in message.split('\n\n')]
    blocks_joined = [single_line_message(block) for block in blocks]
    return u"\n".join(blocks_joined)


def load_overrides(module_name, locals_dict):
    """Load module and language overrides for messages module

    Dynamic override of 'parallels.*.messages' module with language and UI specific messages according
    to environment variables using Python's magic.

    Overrides are applied in the following way:
    - Common UI overrides ('parallels.*.messages.{ui-type}'), where '{ui-type}' is either 'cli' or 'gui'
    - Language overrides ('parallels.*.messages.{language}') where language
    is locale in lowercase (for example, ja_jp')
    - Language UI overrides ('parallels.*.messages.{language}.{ui-type}')

    Arguments:
    module_name is a full name of a root module, which should get overridden values,
    for example 'parallels.core.messages'
    locals_dict is a dictionary of local variables of the module

    So, the call should always look like:
    load_overrides(__name__, locals())
    and be the last line of the module

    :type module_name: str | unicode
    :type locals_dict: dict
    """
    messages_ui = os.getenv('MIGRATOR_MESSAGES_UI')
    if messages_ui is None:
        messages_ui = 'cli'
    # white list of UI type, to avoid loading arbitrary module for security considerations
    allowed_ui = ('cli', 'gui')

    if messages_ui not in allowed_ui:
        messages_ui = 'cli'

    # white list of languages, to avoid loading arbitrary module for security considerations
    allowed_lang = (
        'ar_EG',
        'cs_CZ',
        'da_DK',
        'de_DE',
        'el_GR',
        'en_US',
        'es_ES',
        'fi_FI',
        'fr_FR',
        'he_IL',
        'hu_HU',
        'id_ID',
        'it_IT',
        'ja_JP',
        'ko_KR',
        'ms_MY',
        'nb_NO',
        'nl_NL',
        'pl_PL',
        'pt_BR',
        'pt_PT',
        'ro_RO',
        'ru_RU',
        'sv_SE',
        'th_TH',
        'tl_PH',
        'tr_TR',
        'uk_UA',
        'vi_VN',
        'zh_CN',
        'zh_TW',
    )

    messages_lang = os.getenv('MIGRATOR_MESSAGES_LANG')
    if messages_lang is not None:
        messages_lang = messages_lang.replace('-', '_')
    if messages_lang not in allowed_lang:
        messages_lang = None
    if messages_lang is not None:
        messages_lang = messages_lang.lower()

    _load_overrides_for_submodule(module_name, [messages_ui], locals_dict)

    if messages_lang is not None:
        _load_overrides_for_submodule(module_name, [messages_lang], locals_dict)
        _load_overrides_for_submodule(module_name, [messages_lang, messages_ui], locals_dict)


def _load_overrides_for_submodule(module_name, submodules, locals_dict):
    # determine root directory of all migrator's modules
    root_modules_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..')

    # determine filename of a module to be loaded
    filename = os.path.join(*(
        [root_modules_dir] +
        module_name.split('.') +
        submodules[:len(submodules) - 1] +  # package directories
        ["%s.py" % submodules[len(submodules) - 1]]  # final ".py" file name
    ))

    # check if module actually exists
    if not os.path.exists(filename):
        return

    # import module by Python name
    override_module_name = '.'.join([module_name] + submodules)
    override_module = __import__(override_module_name, globals(), locals(), ['*'])

    # override variables in local variables dictionary of parent module
    for item in dir(override_module):
        if not item.startswith('_') and item.isupper():
            locals_dict[item] = getattr(override_module, item)
