#!/usr/bin/env python3

import os
import datetime

from urllib.request import urlopen


# This script parses the SDL game controller db header file from the
# SDL mercurial repository, and generates a list of mappings to be used
# internally by pyglet. This script may need to be updated if the
# format or url changes.


# Get the raw database header file:
DB_URL = "https://hg.libsdl.org/SDL/raw-file/default/src/joystick/SDL_gamepad_db.h"
raw = urlopen(DB_URL).read().decode('ascii')

# Format the output directory for the pyglet module:
script_dir = os.path.abspath(os.path.dirname(__file__))
output_dir = os.path.join(script_dir, os.path.pardir, 'pyglet', 'input')
output_file = os.path.join(output_dir, 'controller_db.py')

# Parse the Windows section:
win_string = '#ifdef SDL_JOYSTICK_DINPUT'
win_start = raw.find(win_string) + len(win_string)
win_end = raw.find('#endif', win_start)
win_raw = raw[win_start:win_end]

# Parse the Mac OSX section:
mac_string = '#ifdef SDL_PLATFORM_MACOS'
mac_start = raw.find(mac_string) + len(mac_string)
mac_end = raw.find('#endif', mac_start)
mac_raw = raw[mac_start:mac_end]

# Parse the Linux section:
lin_string = '#if defined(SDL_JOYSTICK_LINUX) || defined(SDL_PLATFORM_OPENBSD)'
lin_start = raw.find(lin_string) + len(lin_string)
lin_end = raw.find('#endif', lin_start)
lin_raw = raw[lin_start:lin_end]


def strip_lines(raw_lines):
    """Strip invalid lines and C comments"""
    lines = []
    for line in raw_lines.splitlines():
        line = line.strip()
        if '"' in line:
            line = line.split('"')[1]
            lines.append(line)
    return lines


# Create lists of formatted lines:
win_lines = strip_lines(win_raw)
mac_lines = strip_lines(mac_raw)
lin_lines = strip_lines(lin_raw)


# Write out a valid Python module in the pyglet/input directory:
with open(output_file, 'w+') as f:
    f.write("from pyglet import compat_platform\n\n\n")
    f.write("# This file is automatically generated by 'pyglet/tools/gen_controller_db.py'\n")
    f.write("# Generated on: {0}\n\n".format(datetime.datetime.now().strftime('%c')))

    f.write("""if compat_platform.startswith("linux"):\n    mapping_list = [\n""")
    for lin_line in lin_lines:
        f.write(f'"{lin_line}",\n')
    f.write("]\n")

    f.write("""elif compat_platform.startswith("darwin"):\n    mapping_list = [\n""")
    for mac_line in mac_lines:
        f.write(f'"{mac_line}",\n')
    f.write("]\n")

    f.write("""elif compat_platform.startswith("win"):\n    mapping_list = [\n""")
    for win_line in win_lines:
        f.write(f'"{win_line}",\n')
    f.write("]\n")

    f.write("else:\n    mapping_list = []\n")

print("Saved 'pyglet/input/controller_db.py'")
