#!/usr/bin/python
import os
import sys
from xml.dom import minidom

def _configure_xorg(root, keymap, variant, options):

    print("Configuring X keyboard.")

    confd_dir = os.path.join(root, "etc/X11/xorg.conf.d")
    if not os.path.isdir(confd_dir):
        os.makedirs(confd_dir, 0o755)

    if variant is None:
        variant = ""
    if options is None:
        options = ""

    _conf_skel = """\
Section "InputClass"
       Identifier "keyboard"
       MatchIsKeyboard "yes"
       Option "XkbLayout" "__LAYOUT__"
       Option "XkbVariant" "__VARIANT__"
       Option  "XkbOptions" "__OPTIONS__"
EndSection
"""
    outtxt = _conf_skel.replace("__LAYOUT__", keymap).replace("__VARIANT__",
        variant).replace("__OPTIONS__", options)

    confd_file = os.path.join(confd_dir, "00-keyboard.conf")
    with open(confd_file, "w") as f:
        f.write(outtxt)
        f.flush()

    return 0

def _configure_kde(root, keymap, variant, options):

    print("Configuring KDE keyboard.")

    def _keymap_handler(base_dir):

        config_file = os.path.join(root, base_dir.lstrip(os.path.sep),
            ".kde4/share/config/kxkbrc")
        if not (os.path.isfile(config_file) and \
            os.access(config_file, os.W_OK)):
            return

        output = []
        with open(config_file, "r") as f:

            layout_exists = False
            display_names_exists = False
            layout_list_exists = False

            for line in f.readlines():
                if line.startswith("Layout="):
                    layout_exists = True
                    line = "Layout=%s\n" % (keymap,)
                elif line.startswith("DisplayNames="):
                    display_names_exists = True
                    line = "DisplayNames=%s\n" % (keymap,)
                elif line.startswith("LayoutList="):
                    layout_list_exists = True
                    line = "LayoutList=%s\n" % (keymap,)
                output.append(line)

            if not layout_exists:
                output.append("Layout=%s\n" % (keymap,))
            if not display_names_exists:
                output.append("DisplayNames=%s\n" % (keymap,))
            if not layout_list_exists:
                output.append("LayoutList=%s\n" % (keymap,))

        with open(config_file+".tmp", "w") as f:
            print("Writing to %s" % (config_file,))
            f.writelines(output)
            f.flush()
        os.rename(config_file+".tmp", config_file)

    if os.path.isdir("/home"):
        for user_name in os.listdir("/home"):
            if user_name.startswith("."):
                continue
            _keymap_handler(os.path.join("/home", user_name))
    _keymap_handler("/root")
    _keymap_handler("/etc/skel")

    return 0

def _configure_all(root, keymap, variant, options):
    funcs = (_configure_xorg, _configure_kde)
    for func in funcs:
        rc = func(root, keymap, variant, options)
        if rc != 0:
            return rc
    return 0

VALID_OPTIONS = {
    "xorg": _configure_xorg,
    "kde": _configure_kde,
    "all": _configure_all,
}

def print_help():
    print("Keyboard configuration tool - Sabayon Linux (2011)")
    print("usage: keyboard-setup <keymap> [<variant>] [<options>] <component>")
    print("available components: " + ",".join(sorted(VALID_OPTIONS.keys())))

args = sys.argv[1:]
# print help
if ("--help" in args) or ("-h" in args) or (len(args) < 2):
    print_help()
    if len(args) < 2:
        raise SystemExit(1)
    else:
        raise SystemExit(0)

_component = args[-1]
_root = os.getenv("ROOT", "/")

params = sys.argv[1:-1]
_variant = None
_options = None
_keymap = params.pop(0)
if params:
    _variant = params.pop(0)
if params:
    _options = params.pop(0)
if params:
    # bad syntax
    print_help()
    raise SystemExit(1)

if os.getuid() != 0:
    # root !
    print_help()
    raise SystemExit(1)

func = VALID_OPTIONS.get(_component)
if func is None:
    # bad syntax
    print_help()
    raise SystemExit(1)

rc = func(_root, _keymap, _variant, _options)
raise SystemExit(rc)
