#!/usr/bin/python3
import sys
import glob
import re
from typing import Text
import json

if len(sys.argv) >= 2:
    rootPath = sys.argv[1]
else:
    rootPath = './keybindings.sh'


def readFile(filePath):
    try:
        paths = glob.glob(filePath)
    except (Exception, IndexError):
        print("couldn't resolve glob:", filePath)
        paths = []

    allLines: list[str] = []
    for path in paths:
        allLines = allLines + open(path, "r").readlines()

    finalLines: list[str] = []
    for line in allLines:
        if re.search(r'^include\s+(.+?)$', line):
            nextPath = re.findall(r'^include\s+(.+?)$', line)[0]
            finalLines = finalLines + readFile(nextPath)
        else:
            finalLines = finalLines + [line]

    return finalLines


lines = readFile(rootPath)


def findKeybindingForLine(lineNumber: int, lines: list[str]):
    return lines[lineNumber + 1].split(' ')[3]


class DocsConfig:
    category: Text
    action: Text
    keybinding: Text


def getDocsConfig(lines: list[str]):
    docsLineRegex = r"^## (?P<category>.+?) // (?P<action>.+?)\s+(// (?P<keybinding>.+?))*##"
    docsConfig: list[DocsConfig] = []
    for index, line in enumerate(lines):
        match = re.match(docsLineRegex, line)
        if match:
            config = DocsConfig()
            config.category = match.group('category')
            config.action = match.group('action')
            config.keybinding = match.group('keybinding')
            if config.keybinding is None:
                config.keybinding = findKeybindingForLine(index, lines)
            docsConfig = docsConfig + [config]
    return docsConfig


def getSymbolDict(lines: list[str]):
    setRegex = r"^(?P<variable>\w+)\=\"(?P<value>[^\"]+)+\" ?"
    dictionary = {}
    for line in lines:
        match = re.match(setRegex, line)
        if match:
            if match.group('variable'):
                dictionary['$'+match.group('variable')] = match.group('value')
    return dict(dictionary)


translations = {
    'Mod1': "Alt",
    'Mod2': "NumLk",
    'Mod3': "בּ",
    'Mod4': "",
    'Mod5': "Scroll",
    'question': "?",
    'space': "␣",
    'minus': "-",
    'plus': '+',
    'Return': "Enter",
    'XF86AudioRaiseVolume': "",
    'XF86AudioLowerVolume': "",
    'XF86AudioMute': "",
    'XF86AudioMicMute': '',
    'XF86MonBrightnessUp': "",
    'XF86MonBrightnessDown': "",
    'XF86PowerOff': "",
    'XF86TouchpadToggle': "Toggle Touchpad"
}


def translate(word: Text, dictionary: dict):
    try:
        return dictionary[word.strip()]
    except KeyError:
        return word.strip()


def replaceBindingFromMap(binding: Text, dictionary: dict):
    elements = binding.split('+')
    resultElements = []
    for el in elements:
        translation = translate(translate(el, dictionary), translations)
        resultElements = resultElements + [translation]

    return " + ".join(resultElements)


def sanitize(configs: list[DocsConfig], symbolDict: dict):
    for index, config in enumerate(configs):
        config.keybinding = replaceBindingFromMap(
            config.keybinding, symbolDict)
        configs[index] = config
    return configs


def getDocsList(lines: list[str]):
    docsConfig = getDocsConfig(lines)
    symbolDict = getSymbolDict(lines)
    sanitizedConfig = sanitize(docsConfig, symbolDict)
    return sanitizedConfig


docsList = getDocsList(lines)

result = []
for config in docsList:
    result = result + [{'category': config.category,
                        'action': config.action, 'keybinding': config.keybinding}]
print(json.dumps(result))