from collections.abc import Sequence
import os
import re

from plover.oslayer.config import CONFIG_DIR
from plover.resource import resource_filename
from plover.registry import registry
from plover.steno import Stroke


def _load_wordlist(filename, assets_dir):
    if filename is None:
        return {}
    path = None
    for directory in (CONFIG_DIR, assets_dir):
        if directory is None:
            continue
        path = os.path.join(resource_filename(directory), filename)
        if os.path.exists(path):
            break
    else:
        return {}
    with open(path, encoding="utf-8") as f:
        text = f.read()
    fields = text.split()
    it = iter(fields)
    words = dict(zip(it, map(int, it)))
    assert len(fields) == 2 * len(words), path + " contains duplicate words."
    return words


def _key_order(keys, numbers):
    key_order = {}
    for order, key in enumerate(keys):
        key_order[key] = order
        number_key = numbers.get(key)
        if number_key is not None:
            key_order[number_key] = order
    return key_order


def _suffix_keys(keys):
    assert isinstance(keys, Sequence)
    return keys


_EXPORTS = {
    "KEYS": lambda mod: mod.KEYS,
    "KEY_ORDER": lambda mod: _key_order(mod.KEYS, mod.NUMBERS),
    "NUMBER_KEY": lambda mod: mod.NUMBER_KEY,
    "NUMBERS": lambda mod: dict(mod.NUMBERS),
    "FERAL_NUMBER_KEY": lambda mod: getattr(mod, "FERAL_NUMBER_KEY", False),
    "SUFFIX_KEYS": lambda mod: _suffix_keys(mod.SUFFIX_KEYS),
    "UNDO_STROKE_STENO": lambda mod: mod.UNDO_STROKE_STENO,
    "IMPLICIT_HYPHEN_KEYS": lambda mod: set(mod.IMPLICIT_HYPHEN_KEYS),
    "IMPLICIT_HYPHENS": lambda mod: {
        l.replace("-", "") for l in mod.IMPLICIT_HYPHEN_KEYS
    },
    "ORTHOGRAPHY_WORDS": lambda mod: _load_wordlist(
        mod.ORTHOGRAPHY_WORDLIST, mod.DICTIONARIES_ROOT
    ),
    "ORTHOGRAPHY_RULES": lambda mod: [
        (re.compile(pattern, re.IGNORECASE), replacement)
        for pattern, replacement in mod.ORTHOGRAPHY_RULES
    ],
    "ORTHOGRAPHY_RULES_ALIASES": lambda mod: dict(mod.ORTHOGRAPHY_RULES_ALIASES),
    "KEYMAPS": lambda mod: mod.KEYMAPS,
    "DICTIONARIES_ROOT": lambda mod: mod.DICTIONARIES_ROOT,
    "DEFAULT_DICTIONARIES": lambda mod: mod.DEFAULT_DICTIONARIES,
}


def setup(system_name):
    system_symbols = {}
    system_mod = registry.get_plugin("system", system_name).obj
    for symbol, init in _EXPORTS.items():
        system_symbols[symbol] = init(system_mod)
    system_symbols["NAME"] = system_name
    globals().update(system_symbols)
    Stroke.setup(
        KEYS,
        IMPLICIT_HYPHEN_KEYS,
        NUMBER_KEY,
        NUMBERS,
        FERAL_NUMBER_KEY,
        UNDO_STROKE_STENO,
    )


NAME = None
