import os
import shutil
import string
import subprocess
import configparser

pjoin = os.path.join


def read(filename: str) -> str:
    with open(filename, "r") as file:
        return file.read()


# Prepare `lunch` config template
config_template = string.Template(read("template.toml"))

# Prepare `lunch` config template
meson_template = string.Template(read("config/template.build"))


# Prepare games directory
if os.path.exists("games"):
    shutil.rmtree("games")
os.mkdir("games")
with open("games/.gitignore", "w") as file:
    file.write("*")

# Read config directory
games = []
for dirent in os.listdir("config"):
    path = pjoin("config", dirent)

    # If not a directory, skip
    if not os.path.isdir(path):
        continue

    # Append game's name, and print it to the console
    print(dirent)
    games.append(dirent)

    # Preprocess game config
    config_source = ["[main]"]  # Default section
    for line in read(pjoin(path, "config.ini")).split("\n"):
        line = line.strip()

        # If line empty, skip
        if len(line) == 0:
            continue

        # If key-value missing, set empty
        if (line[0] != "[") and ("=" not in line):
            line += "="
        
        config_source.append(line)
    config_source = "\n".join(config_source)

    # Load game config
    config = configparser.ConfigParser()
    config.read_string(config_source)
    
    # Prepare flat config
    flat_config = {}
    for key in config["main"].keys():
        flat_config[key] = config["main"][key]

    # Set defaults
    def default(key, value):
        if key not in flat_config:
            flat_config[key] = value

    default("name", dirent)
    default("exec", dirent+".exe")
    default("workdir", "")

    # Replace slashes for paths
    for key in ["exec", "workdir"]:
        flat_config[key] = flat_config[key].replace("\\", "/")

    # Add exclusions
    if "exclude" in config:
        flat_config["exclusions"] = list(config["exclude"].keys())
    else:
        flat_config["exclusions"] = []

    # Prepare game directory
    opath = pjoin("games", dirent)
    os.mkdir(opath)
    
    # Generate `lunch` config
    with open(pjoin(opath, "config.toml"), "w") as file:
        file.write(config_template.substitute(dict(flat_config)))

    # Generate icon
    icon_png = pjoin(path,  "icon.png")
    icon     = pjoin(opath, "icon.ico")
    subprocess.run([
        "magick",
        icon_png,
        "-resize", "256x256",
        "-define", "icon:auto-resize=256,128,96,64,48,32,16",
        icon,
    ])

    # Generate resource file
    with open(pjoin(opath, "resource.rc"), "w") as file:
        file.writelines([
            "ICON\tICON\t\"icon.ico\""
        ])

    # Generate source file
    with open(pjoin(opath, "main.d"), "w") as file:
        file.writelines([
            "module main;\n",
            "\n",
            "import lunch.app;\n",
            "\n",
            "\n",
            "void main()\n",
            "{\n",
            "    app(import(\"config.toml\"));\n",
            "}\n",
        ])

    # Generate meson file
    with open(pjoin(opath, "meson.build"), "w") as file:
        file.write(meson_template.substitute(dict(flat_config)))


# Prepare meson configuration
mesontemplate = string.Template(read("config/meson.build"))
meson = {
    "games": games
}

# Generate meson.build
with open("games/meson.build", "w") as file:
    file.write(mesontemplate.substitute(meson))