import re

def parse_inf_file(inf_path):
    with open(inf_path, 'r', encoding='utf-8') as f:
        lines = f.readlines()

    current_section = None
    sections = {}
    strings = {}
    for line in lines:
        line = line.strip()
        if not line or line.startswith(';'):
            continue
        if line.startswith('[') and line.endswith(']'):
            current_section = line[1:-1]
            sections[current_section] = []
        elif current_section:
            sections[current_section].append(line)
            if current_section.lower() == 'strings' and '=' in line:
                key, value = line.split('=', 1)
                strings[key.strip()] = value.strip().replace('"', '')

    return sections, strings

def convert_addreg_entry(entry):
    match = re.match(r'^\s*(HK[L|C][M|R])\s*,\s*"?([^,"]*)"?\s*,\s*"?([^",]*)"?\s*,\s*([^,]*)\s*,\s*(.*)\s*$', entry)
    if match:
        hive, key, value_name, flags, value_data = match.groups()
        reg_type = "FIX UNKNOWN " + flags
        value_data = value_data.replace('" , "', '","').replace('", "', '","').replace('" ,"', '","')
        parts = value_data.split('","')
        value_data = '\\0'.join(parts).replace('"', '')

        flags = flags.strip()
        match flags:
            case '0' | '0x00000000' | '0x00000001' | '':
                reg_type = 'REG_SZ'
            case '0x00010001' | '0x10001':
                reg_type = 'REG_DWORD'
            case '0x00000003':
                reg_type = 'REG_BINARY'
            case '0x00020000':
                reg_type = 'REG_EXPAND_SZ'
            case '0x00010000':
                reg_type = 'REG_MULTI_SZ'
            case _:
                print(flags)
                exit

        value_name = value_name if value_name else ''
        value_data = value_data if value_data else ''
        return f'REG ADD "{hive}\\{key}" /v "{value_name}" /t {reg_type} /d "{value_data}" /f'
    else:
        match = re.match(r'^\s*(HK[L|C][M|R])\s*,\s*"?([^,"]*)"?\s*,\s*"?([^",]*)"?\s*,\s*([^,]*)?$', entry)
        if match:
            hive, key, value_name, flags = match.groups()
            return f'REG ADD "{hive}\\{key}" /f'
    return f':: Unable to parse AddReg entry: {entry}'

def convert_delreg_entry(entry):
    match = re.match(r'(HK[LMCR]),\s*([^,]+)(?:,\s*"?([^"]*)"?)?', entry)
    if match:
        hive, key, value_name = match.groups()
        if value_name:
            return f'REG DELETE "{hive}\\{key}" /v "{value_name}" /f'
        else:
            return f'REG DELETE "{hive}\\{key}" /f'
    return f':: Unable to parse DelReg entry: {entry}'

def convert_copyfiles_section(section_name, sections):
    commands = []
    files = sections.get(section_name, [])
    for file in files:
        commands.append(f'COPY "{file}" "%SystemRoot%\\System32\\"')
    return commands

def convert_linkitems_entry(entry, strings):
    key, value = entry.split('=', 1)
    key = key.strip()
    parts = re.findall(r'"[^"]*"|[^,]+', value)
    parts = [p.strip().strip('"') for p in parts]

    shortcut_name = strings.get(key, key)
    shortcut_dir = strings.get(parts[1], parts[1])
    target_path = strings.get(parts[2], parts[2])
    arguments = strings.get(parts[3], parts[3])
    working_dir = strings.get(parts[5], parts[5])
    tooltip = strings.get(parts[8], parts[8])

    shortcut_path = f"{shortcut_dir}\\{shortcut_name}.lnk"

    # Generate VBScript to create the shortcut
    vbs_lines = [
        'echo Set oWS = WScript.CreateObject("WScript.Shell") > create_shortcut.vbs',
        f'echo sLinkFile = "{shortcut_path}" >> create_shortcut.vbs',
        'echo Set oLink = oWS.CreateShortcut(sLinkFile) >> create_shortcut.vbs',
        f'echo oLink.TargetPath = "{target_path}" >> create_shortcut.vbs',
        f'echo oLink.Arguments = "{arguments}" >> create_shortcut.vbs',
        f'echo oLink.WorkingDirectory = "{working_dir}" >> create_shortcut.vbs',
        f'echo oLink.Description = "{tooltip}" >> create_shortcut.vbs',
        'echo oLink.Save >> create_shortcut.vbs',
        'cscript //nologo create_shortcut.vbs',
        'del create_shortcut.vbs'
    ]

    return '\n'.join(vbs_lines)


def substitute_variables(line, strings):
    for key, value in strings.items():
        line = line.replace(f'%{key}%', value)
    return line

def generate_batch_script(sections, strings, output_path):
    with open(output_path, 'w', encoding='utf-8') as f:
        f.write('@echo off\n\n')
        # Handle AddReg
        for section_name in sections:
            if 'reg' in section_name.lower() and 'add' in section_name.lower():
                for entry in sections[section_name]:
                    entry = substitute_variables(entry, strings)
                    f.write(convert_addreg_entry(entry) + '\n')
        f.write('\n')
        # Handle DelReg
        for section_name in sections:
            if section_name.lower().startswith('product') and 'del' in section_name.lower():
                for entry in sections[section_name]:
                    entry = substitute_variables(entry, strings)
                    f.write(convert_delreg_entry(entry) + '\n')
        f.write('\n')
        # Handle CopyFiles
        for section_name in sections:
            if section_name.lower().endswith('.files'):
                copy_commands = convert_copyfiles_section(section_name, sections)
                for cmd in copy_commands:
                    f.write(cmd + '\n')
        f.write('\n')
        # Handle LinkItems.Create
        for section_name in sections:
            if section_name.lower() == 'linkitems.create':
                for entry in sections[section_name]:
                    entry = substitute_variables(entry, strings)
                    f.write(convert_linkitems_entry(entry, strings) + '\n')
        f.write('\npause\n')

# Example usage
inf_file_path = 'update.inf'
output_bat_path = 'converted_update_inf.bat'
sections, strings = parse_inf_file(inf_file_path)
generate_batch_script(sections, strings, output_bat_path)
