#!/usr/bin/python
# -*- python -*-
#
# Keycode Map Generator
#
# Copyright (C) 2009-2017 Red Hat, Inc.
#
# This file is dual license under the terms of the GPLv2 or later
# and 3-clause BSD licenses.
#

# Requires >= 2.6
from __future__ import print_function

import csv
import argparse
import hashlib
import time
import sys

class Database:

    # Linux: linux/input.h
    MAP_LINUX = "linux"

    # OS-X: Carbon/HIToolbox/Events.h
    MAP_OSX = "osx"

    # AT Set 1: linux/drivers/input/keyboard/atkbd.c
    #           (atkbd_set2_keycode + atkbd_unxlate_table)
    MAP_ATSET1 = "atset1"

    # AT Set 2: linux/drivers/input/keyboard/atkbd.c
    #           (atkbd_set2_keycode)
    MAP_ATSET2 = "atset2"

    # AT Set 3: linux/drivers/input/keyboard/atkbd.c
    #           (atkbd_set3_keycode)
    MAP_ATSET3 = "atset3"

    # Linux RAW: linux/drivers/char/keyboard.c (x86_keycodes)
    MAP_XTKBD = "xtkbd"

    # USB HID: linux/drivers/hid/usbhid/usbkbd.c (usb_kbd_keycode)
    MAP_USB = "usb"

    # Win32: mingw32/winuser.h
    MAP_WIN32 = "win32"

    # XWin XT: xorg-server/hw/xwin/{winkeybd.c,winkeynames.h}
    #          (xt + manually transcribed)
    MAP_XWINXT = "xwinxt"

    # X11: http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
    MAP_X11 = "x11"

    # XKBD XT: xf86-input-keyboard/src/at_scancode.c
    #          (xt + manually transcribed)
    MAP_XKBDXT = "xkbdxt"

    # Xorg with evdev: linux + an offset
    MAP_XORGEVDEV = "xorgevdev"

    # Xorg with kbd: xkbdxt + an offset
    MAP_XORGKBD = "xorgkbd"

    # Xorg with OS-X: osx + an offset
    MAP_XORGXQUARTZ = "xorgxquartz"

    # Xorg + Cygwin: xwinxt + an offset
    MAP_XORGXWIN = "xorgxwin"

    # XT over RFB: xtkbd + special re-encoding of high bit
    MAP_RFB = "rfb"

    MAP_LIST = (
        MAP_LINUX,
        MAP_OSX,
        MAP_ATSET1,
        MAP_ATSET2,
        MAP_ATSET3,
        MAP_USB,
        MAP_WIN32,
        MAP_XWINXT,
        MAP_XKBDXT,
        MAP_X11,

        # These are derived from maps above
        MAP_XTKBD,
        MAP_XORGEVDEV,
        MAP_XORGKBD,
        MAP_XORGXQUARTZ,
        MAP_XORGXWIN,
        MAP_RFB,
    )

    CODE_COLUMNS = {
        MAP_LINUX: 1,
        MAP_OSX: 3,
        MAP_ATSET1: 4,
        MAP_ATSET2: 5,
        MAP_ATSET3: 6,
        MAP_USB: 7,
        MAP_WIN32: 9,
        MAP_XWINXT: 10,
        MAP_XKBDXT: 11,
        MAP_X11: 13,
    }

    NAME_COLUMNS = {
        MAP_LINUX: 0,
        MAP_OSX: 2,
        MAP_WIN32: 8,
        MAP_X11: 12,
    }

    def __init__(self):

        self.mapto = {}
        self.mapfrom = {}
        self.mapname = {}
        self.mapchecksum = None

        for name in self.MAP_LIST:
            # Key is a MAP_LINUX, value is a MAP_XXX
            self.mapto[name] = {}
            # key is a MAP_XXX, value is a MAP_LINUX
            self.mapfrom[name] = {}

        for name in self.NAME_COLUMNS.keys():
            # key is a MAP_LINUX, value is a string
            self.mapname[name] = {}

    def _generate_checksum(self, filename):
        hash = hashlib.sha256()
        with open(filename, "rb") as f:
            for chunk in iter(lambda: f.read(4096), b""):
                hash.update(chunk)
        self.mapchecksum = hash.hexdigest()

    def load(self, filename):
        self._generate_checksum(filename)

        with open(filename, 'r') as f:
            reader = csv.reader(f)

            first = True

            for row in reader:
                # Discard column headings
                if first:
                    first = False
                    continue

                # We special case MAP_LINUX since that is out
                # master via which all other mappings are done
                linux = self.load_linux(row)

                # Now load all the remaining master data values
                self.load_data(row, linux)

                # Then load all the keycode names
                self.load_names(row, linux)

                # Finally calculate derived key maps
                self.derive_data(row, linux)

    def load_linux(self, row):
        col = self.CODE_COLUMNS[self.MAP_LINUX]
        linux = row[col]

        if linux.startswith("0x"):
            linux = int(linux, 16)
        else:
            linux = int(linux, 10)

        self.mapto[self.MAP_LINUX][linux] = linux
        self.mapfrom[self.MAP_LINUX][linux] = linux

        return linux


    def load_data(self, row, linux):
        for mapname in self.CODE_COLUMNS:
            if mapname == self.MAP_LINUX:
                continue

            col = self.CODE_COLUMNS[mapname]
            val = row[col]

            if val == "":
                continue

            if val.startswith("0x"):
                val = int(val, 16)
            else:
                val = int(val, 10)

            self.mapto[mapname][linux] = val
            self.mapfrom[mapname][val] = linux

    def load_names(self, row, linux):
        for mapname in self.NAME_COLUMNS:
            col = self.NAME_COLUMNS[mapname]
            val = row[col]

            if val == "":
                continue

            self.mapname[mapname][linux] = val


    def derive_data(self, row, linux):
        # Linux RAW is XT scan codes with special encoding of the
        # 0xe0 scan codes
        if linux in self.mapto[self.MAP_ATSET1]:
            at1 = self.mapto[self.MAP_ATSET1][linux]
            if at1 > 0x7f:
                assert((at1 & ~0x7f) == 0xe000)
                xtkbd = 0x100 | (at1 & 0x7f)
            else:
                xtkbd = at1
            self.mapto[self.MAP_XTKBD][linux] = xtkbd
            self.mapfrom[self.MAP_XTKBD][xtkbd] = linux

        # Xorg KBD is XKBD XT offset by 8
        if linux in self.mapto[self.MAP_XKBDXT]:
            xorgkbd = self.mapto[self.MAP_XKBDXT][linux] + 8
            self.mapto[self.MAP_XORGKBD][linux] = xorgkbd
            self.mapfrom[self.MAP_XORGKBD][xorgkbd] = linux

        # Xorg evdev is Linux offset by 8
        self.mapto[self.MAP_XORGEVDEV][linux] = linux + 8
        self.mapfrom[self.MAP_XORGEVDEV][linux + 8] = linux

        # Xorg XQuartx is OS-X offset by 8
        if linux in self.mapto[self.MAP_OSX]:
            xorgxquartz = self.mapto[self.MAP_OSX][linux] + 8
            self.mapto[self.MAP_XORGXQUARTZ][linux] = xorgxquartz
            self.mapfrom[self.MAP_XORGXQUARTZ][xorgxquartz] = linux

        # Xorg Xwin (aka Cygwin) is XWin XT offset by 8
        if linux in self.mapto[self.MAP_XWINXT]:
            xorgxwin = self.mapto[self.MAP_XWINXT][linux] + 8
            self.mapto[self.MAP_XORGXWIN][linux] = xorgxwin
            self.mapfrom[self.MAP_XORGXWIN][xorgxwin] = linux

        # RFB keycodes are XT scan codes with a slightly
        # different encoding of 0xe0 scan codes
        if linux in self.mapto[self.MAP_ATSET1]:
            at1 = self.mapto[self.MAP_ATSET1][linux]
            if at1 > 0x7f:
                assert((at1 & ~0x7f) == 0xe000)
                rfb = 0x80 | (at1 & 0x7f)
            else:
                rfb = at1
            self.mapto[self.MAP_RFB][linux] = rfb
            self.mapfrom[self.MAP_RFB][rfb] = linux

class LanguageGenerator(object):

    def _boilerplate(self, lines):
        raise NotImplementedError()

    def generate_header(self, database, args):
        today = time.strftime("%Y-%m-%d %H:%M")
        self._boilerplate([
            "This file is auto-generated from keymaps.csv on %s" % today,
            "Database checksum sha256(%s)" % database.mapchecksum,
            "To re-generate, run:",
            "  %s" % args,
        ])

class LanguageSrcGenerator(LanguageGenerator):

    def _array_start_code(self, varname, length):
        raise NotImplementedError()

    def _array_start_name(self, varname, length):
        raise NotImplementedError()

    def _array_end(self):
        raise NotImplementedError()

    def _array_entry_code(self, index, value, comment):
        raise NotImplementedError()

    def _array_entry_name(self, index, value, comment):
        raise NotImplementedError()

    def generate_code_map(self, varname, database, frommapname, tomapname):
        if frommapname not in database.mapfrom:
            raise Exception("Unknown map %s, expected one of %s" % (
                            frommapname, ", ".join(database.mapfrom.keys())))
        if tomapname not in database.mapto:
            raise Exception("Unknown map %s, expected one of %s" % (
                            tomapname, ", ".join(database.mapto.keys())))

        tolinux = database.mapfrom[frommapname]
        fromlinux = database.mapto[tomapname]

        if varname is None:
            varname = "code_map_%s_to_%s" % (frommapname, tomapname)

        frommax = 0
        for key in tolinux.keys():
            if key > frommax:
                frommax = key

        self._array_start_code(varname, frommax + 1)
        for src in range(frommax + 1):
            linux = tolinux.get(src, None)
            if linux is None:
                dst = None
            else:
                dst = fromlinux.get(linux, None)

            comment = "%s -> %s -> %s" % (self._label(database, frommapname, src, linux),
                                          self._label(database, Database.MAP_LINUX, linux, linux),
                                          self._label(database, tomapname, dst, linux))
            self._array_entry_code(src, dst, comment)
        self._array_end()                                        

    def generate_code_table(self, varname, database, mapname):
        if mapname not in database.mapto:
            raise Exception("Unknown map %s, expected one of %s" % (
                            mapname, ", ".join(database.mapto.keys())))

        keys = database.mapto[Database.MAP_LINUX].keys()
        keys.sort()
        names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for key in keys]

        if varname is None:
            varname = "code_table_%s" % mapname

        self._array_start_code(varname, len(keys))

        for i in range(len(keys)):
            key = keys[i]
            dst = database.mapto[mapname].get(key, None)
            self._array_entry_code(i, dst, names[i])

        self._array_end()

    def generate_name_map(self, varname, database, frommapname, tomapname):
        if frommapname not in database.mapfrom:
            raise Exception("Unknown map %s, expected one of %s" % (
                            frommapname, ", ".join(database.mapfrom.keys())))
        if tomapname not in database.mapname:
            raise Exception("Unknown map %s, expected one of %s" % (
                            tomapname, ", ".join(database.mapname.keys())))

        tolinux = database.mapfrom[frommapname]
        fromlinux = database.mapname[tomapname]

        if varname is None:
            varname = "name_map_%s_to_%s" % (frommapname, tomapname)

        frommax = 0
        for key in tolinux.keys():
            if key > frommax:
                frommax = key

        self._array_start_name(varname, frommax + 1)

        for src in range(frommax + 1):
            linux = tolinux.get(src, None)
            if linux is None:
                dst = None
            else:
                dst = fromlinux.get(linux, None)

            comment = "%s -> %s -> %s" % (self._label(database, frommapname, src, linux),
                                          self._label(database, Database.MAP_LINUX, linux, linux),
                                          self._label(database, tomapname, dst, linux))
            self._array_entry_name(src, dst, comment)
        self._array_end()                                        

    def generate_name_table(self, varname, database, mapname):
        if mapname not in database.mapname:
            raise Exception("Unknown map %s, expected one of %s" % (
                            mapname, ", ".join(database.mapname.keys())))

        keys = database.mapto[Database.MAP_LINUX].keys()
        keys.sort()
        names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for key in keys]

        if varname is None:
            varname = "name_table_%s" % mapname

        self._array_start_name(varname, len(keys))

        for i in range(len(keys)):
            key = keys[i]
            dst = database.mapname[mapname].get(key, None)
            self._array_entry_name(i, dst, names[i])

        self._array_end()

    def _label(self, database, mapname, val, linux):
        if mapname in database.mapname:
            return "%s:%s (%s)" % (mapname, val, database.mapname[mapname].get(linux, "unnamed"))
        else:
            return "%s:%s" % (mapname, val)

class LanguageDocGenerator(LanguageGenerator):

    def _array_start_name_doc(self, varname, namemap):
        raise NotImplementedError()

    def _array_start_code_doc(self, varname, namemap, codemap):
        raise NotImplementedError()

    def _array_end(self):
        raise NotImplementedError()

    def _array_name_entry(self, value, name):
        raise NotImplementedError()

    def _array_code_entry(self, value, name):
        raise NotImplementedError()

    def generate_name_docs(self, varname, database, mapname):
        if mapname not in database.mapname:
            raise Exception("Unknown map %s, expected one of %s" % (
                            mapname, ", ".join(database.mapname.keys())))

        keys = database.mapto[Database.MAP_LINUX].keys()
        keys.sort()
        names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for key in keys]

        if varname is None:
            varname = mapname

        self._array_start_name_doc(varname, mapname)

        for i in range(len(keys)):
            key = keys[i]
            dst = database.mapname[mapname].get(key, None)
            self._array_name_entry(key, dst)

        self._array_end()


    def generate_code_docs(self, varname, database, mapname):
        if mapname not in database.mapfrom:
            raise Exception("Unknown map %s, expected one of %s" % (
                            mapname, ", ".join(database.mapfrom.keys())))

        tolinux = database.mapfrom[mapname]
        keys = tolinux.keys()
        keys.sort()
        if mapname in database.mapname:
            names = database.mapname[mapname]
            namemap = mapname
        else:
            names = database.mapname[Database.MAP_LINUX]
            namemap = Database.MAP_LINUX

        if varname is None:
            varname = mapname

        self._array_start_code_doc(varname, mapname, namemap)

        for i in range(len(keys)):
            key = keys[i]
            self._array_code_entry(key, names.get(tolinux[key], "unnamed"))

        self._array_end()

class CLanguageGenerator(LanguageSrcGenerator):

    def __init__(self, inttypename, strtypename):
        self.inttypename = inttypename
        self.strtypename = strtypename

    def _boilerplate(self, lines):
        print("/*")
        for line in lines:
            print(" * %s" % line)
        print("*/")

    def _array_start_code(self, varname, length):
        print("const %s %s[%d] = {" % (self.inttypename, varname, length))

    def _array_start_name(self, varname, length):
        print("const %s %s[%d] = {" % (self.strtypename, varname, length))

    def _array_end(self):
        print("};")

    def _array_entry_code(self, index, value, comment):
        if value is not None:
            print("  [0x%x] = 0x%x, /* %s */" % (index, value, comment))

    def _array_entry_name(self, index, value, comment):
        if value is not None:
            print("  [0x%x] = \"%s\", /* %s */" % (index, value, comment))

class CppLanguageGenerator(CLanguageGenerator):

    # designated initializers not available in C++
    def _array_entry_code(self, index, value, comment):
        if value is not None:
            print("  0x%x, /* %s */" % (value, comment))
        else:
            print("  0, /* %s */" % comment)

    def _array_entry_name(self, index, value, comment):
        if value is not None:
            print("  \"%s\", /* %s */" % (value, comment))
        else:
            print("  0, /* %s */" % comment)

class StdCLanguageGenerator(CLanguageGenerator):

    def __init__(self):
        super(StdCLanguageGenerator, self).__init__("unsigned short", "char *")

class StdCppLanguageGenerator(CppLanguageGenerator):

    def __init__(self):
        super(StdCppLanguageGenerator, self).__init__("unsigned short", "char *")

class GLib2LanguageGenerator(CLanguageGenerator):

    def __init__(self):
        super(GLib2LanguageGenerator, self).__init__("guint16", "gchar *")

class PythonLanguageGenerator(LanguageSrcGenerator):

    def _boilerplate(self, lines):
        print("#")
        for line in lines:
            print("# %s" % line)
        print("#")

    def _array_start_code(self, varname, length):
        print("%s = [" % varname)

    def _array_start_name(self, varname, length):
        print("%s = [" % varname)

    def _array_end(self):
        print("]")

    def _array_entry_code(self, index, value, comment):
        if value is None:
            print("  None, # %s" % (comment))
        else:
            print("  0x%x, # %s" % (value, comment))

    def _array_entry_name(self, index, value, comment):
        if value is None:
            print("  None, # %s" % (comment))
        else:
            print("  \"%s\", # %s" % (value, comment))

class PerlLanguageGenerator(LanguageSrcGenerator):

    def _boilerplate(self, lines):
        print("#")
        for line in lines:
            print("# %s" % line)
        print("#")

    def _array_start_code(self, varname, length):
        print("my @%s = (" % varname)

    def _array_start_name(self, varname, length):
        print("my @%s = (" % varname)

    def _array_end(self):
        print(");")

    def _array_entry_code(self, index, value, comment):
        if value is None:
            print("  undef, # %s" % (comment))
        else:
            print("  0x%x, # %s" % (value, comment))

    def _array_entry_name(self, index, value, comment):
        if value is None:
            print("  undef, # %s" % (comment))
        else:
            print("  \"%s\", # %s" % (value, comment))

class PodLanguageGenerator(LanguageDocGenerator):

    def _boilerplate(self, lines):
        print("#")
        for line in lines:
            print("# %s" % line)
        print("#")

    def _array_start_name_doc(self, varname, namemap):
        print("=head1 %s" % varname)
        print("")
        print("List of %s key code names, with corresponding key code values" % namemap)
        print("")
        print("=over 4")
        print("")

    def _array_start_code_doc(self, varname, codemap, namemap):
        print("=head1 %s" % varname)
        print("")
        print("List of %s key code values, with corresponding %s key code names" % (codemap, namemap))
        print("")
        print("=over 4")
        print("")

    def _array_end(self):
        print("=back")
        print("")

    def _array_name_entry(self, value, name):
        print("=item %s" % name)
        print("")
        print("Key value %d (0x%x)" % (value, value))
        print("")

    def _array_code_entry(self, value, name):
        print("=item %d (0x%x)" % (value, value))
        print("")
        print("Key name %s" % name)
        print("")

SRC_GENERATORS = {
    "stdc": StdCLanguageGenerator(),
    "stdc++": StdCppLanguageGenerator(),
    "glib2": GLib2LanguageGenerator(),
    "python2": PythonLanguageGenerator(),
    "python3": PythonLanguageGenerator(),
    "perl": PerlLanguageGenerator(),
}
DOC_GENERATORS = {
    "pod": PodLanguageGenerator(),
}

def code_map(args):
    database = Database()
    database.load(args.keymaps)

    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["code-map", "keymaps.csv", args.frommapname, args.tomapname])
    SRC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    SRC_GENERATORS[args.lang].generate_code_map(args.varname, database, args.frommapname, args.tomapname)

def code_table(args):
    database = Database()
    database.load(args.keymaps)

    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["code-table", "keymaps.csv", args.mapname])
    SRC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    SRC_GENERATORS[args.lang].generate_code_table(args.varname, database, args.mapname)

def name_map(args):
    database = Database()
    database.load(args.keymaps)

    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["name-map", "keymaps.csv", args.frommapname, args.tomapname])
    SRC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    SRC_GENERATORS[args.lang].generate_name_map(args.varname, database, args.frommapname, args.tomapname)

def name_table(args):
    database = Database()
    database.load(args.keymaps)


    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["name-table", "keymaps.csv", args.mapname])
    SRC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    SRC_GENERATORS[args.lang].generate_name_table(args.varname, database, args.mapname)

def code_docs(args):
    database = Database()
    database.load(args.keymaps)


    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["code-docs", "keymaps.csv", args.mapname])
    DOC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    DOC_GENERATORS[args.lang].generate_code_docs(args.varname, database, args.mapname)

def name_docs(args):
    database = Database()
    database.load(args.keymaps)


    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["name-docs", "keymaps.csv", args.mapname])
    DOC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    DOC_GENERATORS[args.lang].generate_name_docs(args.varname, database, args.mapname)

def usage():
    print ("Please select a command:")
    print ("  'code-map', 'code-table', 'name-map', 'name-table', 'docs'")
    sys.exit(1)

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument("--lang", default="stdc",
                        help="Output language, (src=%s, doc=%s)" % (
                            ",".join(SRC_GENERATORS.keys()),
                            ",".join(DOC_GENERATORS.keys())))
    parser.add_argument("--varname", default=None,
                        help="Data variable name")

    subparsers = parser.add_subparsers(help="sub-command help")

    codemapparser = subparsers.add_parser("code-map", help="Generate a mapping between code tables")
    codemapparser.add_argument("keymaps", help="Path to keymap CSV data file")
    codemapparser.add_argument("frommapname", help="Source code table name")
    codemapparser.add_argument("tomapname", help="Target code table name")
    codemapparser.set_defaults(func=code_map)

    codetableparser = subparsers.add_parser("code-table", help="Generate a flat code table")
    codetableparser.add_argument("keymaps", help="Path to keymap CSV data file")
    codetableparser.add_argument("mapname", help="Code table name")
    codetableparser.set_defaults(func=code_table)

    namemapparser = subparsers.add_parser("name-map", help="Generate a mapping to names")
    namemapparser.add_argument("keymaps", help="Path to keymap CSV data file")
    namemapparser.add_argument("frommapname", help="Source code table name")
    namemapparser.add_argument("tomapname", help="Target name table name")
    namemapparser.set_defaults(func=name_map)

    nametableparser = subparsers.add_parser("name-table", help="Generate a flat name table")
    nametableparser.add_argument("keymaps", help="Path to keymap CSV data file")
    nametableparser.add_argument("mapname", help="Name table name")
    nametableparser.set_defaults(func=name_table)

    codedocsparser = subparsers.add_parser("code-docs", help="Generate code documentation")
    codedocsparser.add_argument("keymaps", help="Path to keymap CSV data file")
    codedocsparser.add_argument("mapname", help="Code table name")
    codedocsparser.set_defaults(func=code_docs)

    namedocsparser = subparsers.add_parser("name-docs", help="Generate name documentation")
    namedocsparser.add_argument("keymaps", help="Path to keymap CSV data file")
    namedocsparser.add_argument("mapname", help="Name table name")
    namedocsparser.set_defaults(func=name_docs)

    args = parser.parse_args()
    if hasattr(args, "func"):
        args.func(args)
    else:
        usage()


main()
