#!/usr/bin/env python3

import os
import sys
import subprocess
import re
import argparse

def get_symvers_in_dir(modsymDir):
    #Support dkms installations with multiple .symvers files
    symversFiles = []
    for (dirpath, dirnames, filenames) in os.walk(modsymDir):
        for filename in filenames:
            if filename.endswith(".symvers"):
                symversFiles.append(dirpath + "/" + filename)

    return symversFiles



parser = argparse.ArgumentParser(description='A utility to search for symvers files for dkms kernel modules')
parser.add_argument('modname', help='Name of the module to search for a symvers file for.', nargs='+')
parser.add_argument('-q', '--quiet', default=False, action='store_true', help='Request no output on errors')

args = parser.parse_args()
modnames = args.modname
quiet_err = args.quiet

uname = os.uname()
symvers_files = []
for modname in modnames:
    modstat = subprocess.run(
        ['/usr/sbin/dkms', '-k', uname.release, 'status', modname],
        capture_output=True, text=True,
    )
    if modstat.returncode == 0 and modstat.stdout:
        #Newer versions of dkms display "<modname>/<version>..." instead of the old "<modname>, <version> ..."
        temp =  modstat.stdout.split(':')[0]
        modstat = re.split(', |/', temp) 
        if len(modstat) >= 4:
            modvers = modstat[1]
            mkvers = modstat[2]
            march = modstat[3]
            modsymDir = os.path.join(
                '/var/lib/dkms',
                modname,
                modvers,
                mkvers,
                march
            )

            symvers_files += get_symvers_in_dir(modsymDir)
if len(symvers_files) > 0:
    print(" ".join(symvers_files))
else:
    #not found in a dkms installation
    #search the manual install location
    for modname in modnames:
        modsymDir = os.path.join('/var/cache', modname)
        symvers_files += get_symvers_in_dir(modsymDir)
    if len(symvers_files) > 0:
        print(" ".join(symvers_files))
    else:
        #We only get here if we did not find the symvers above
        if quiet_err:
            exit(1)
        exit("Module '{}' symvers file could not be found.".format(modname))
