#!/usr/bin/env python3
#-----------------------------------------------------------
#
# Find all devices which have subcircuit definitions in the path
# skywater-pdk/libraries/sky130_fd_pr/VERSION/cells/.  List all of
# these devices.  Then find all paths from the directory models/
# that will read the subcircuit definition through a hierarchical
# series of includes.
#-----------------------------------------------------------

import re
import os 
import sys

#-----------------------------------------------------------
# Find all models in the model directory path, recursively
#-----------------------------------------------------------

def addmodels(modelpath):
    modelfmts = os.listdir(modelpath)
    files_to_parse = []
    for modelfmt in modelfmts:
        if os.path.isdir(modelpath + '/' + modelfmt):
            files_to_parse.extend(addmodels(modelpath + '/' + modelfmt))
        else:
            fmtext = os.path.splitext(modelfmt)[1]
            if fmtext == '.spice':
                files_to_parse.append(modelpath + '/' + modelfmt)

    return files_to_parse

#-----------------------------------------------------------
# Find the device name in a SPICE "X" line
#-----------------------------------------------------------

def get_device_name(line):
    # The instance name has already been parsed out of the line, and
    # all continuation lines have been added, so this routine finds
    # the last keyword that is not a parameter (i.e., does not contain
    # '=').

    tokens = line.split()
    for token in tokens:
        if '=' in token:
            break
        else:
            devname = token

    return devname

#-----------------------------------------------------------
# Pick the file from the list that is appropriate for the
# choice of either FEOL or BEOL corner.  Mostly ad-hoc rules
# based on the known file names.
#-----------------------------------------------------------

def choose_preferred(inclist, feol, beol, notop, debug):

    try:
        # The top-level file 'sky130.lib.spice' is always preferred
        incfile = next(item for item in inclist if os.path.split(item)[1] == 'sky130.lib.spice')
    except:
        # (1) Sort list by the length of the root name of the file
        inclist = sorted(inclist, key=lambda x: len(os.path.splitext(os.path.split(x)[1])[0]))

        # (2) Sort list by depth of directory hierarchy
        inclist = sorted(inclist, key=lambda x: len(x.split('/')))

        for incfile in inclist:
            incname = os.path.split(incfile)[1]
            if debug:
                print('       choose preferred, checking: "' + incname + '"')

            elif incname == 'custom.spice':
                # Ignore "custom.spice" (example file, unused)
                continue
            elif notop and incname.startswith('correl'):
                # Ignore "correl1.spice", etc., if "-notop" option chosen
                continue

            elif feol in incname:
                break
            elif 't' in beol and 'typical' in incname:
                break
            elif 'h' in beol and 'high' in incname:
                break;
            elif 'l' in beol and 'low' in incname:
                break;

    if debug:
        incname = os.path.split(incfile)[1]
        print('      choose_preferred:  chose ' + incfile + ' (' + incname + ')')
    return incfile

#---------------------------------------------------------------------
# Sort files with the subcircuit by relevance.  Files are considered
# in the order ".model.spice", ".pm3.spice", and ".spice".
#---------------------------------------------------------------------

def preferred_order(subfiles, feol):
    ordfiles = []
    feolstr = '__' + feol

    # Sort by length first, so shorter ones, e.g., without "leak" or
    # "discrete", end up at the front of the list.
    ordlist = sorted(subfiles, key=len)

    for file in ordlist[:]:
        if file.endswith('.corner.spice') and feolstr in file:
            ordfiles.append(file)
            ordlist.remove(file)

    for file in ordlist[:]:
        if file.endswith('.model.spice'):
            ordfiles.append(file)
            ordlist.remove(file)

    for file in ordlist[:]:
        if file.endswith('.pm3.spice') and feolstr in file:
            ordfiles.append(file)
            ordlist.remove(file)

    for file in ordlist[:]:
        if file.endswith('.pm3.spice'):
            ordfiles.append(file)
            ordlist.remove(file)

    ordfiles.extend(ordlist)
    return ordfiles

#-----------------------------------------------------------
# Find the appropriate file to include to handle this device
#-----------------------------------------------------------

def check_device(subfiles, includedict, modfilesdict, feol, beol, notop, debug):
    # subfiles = list of files that define this subcircuit.
    # includedict  = files that include the dictionary keyword file
    # modfilesdict = files that are included by the dictionary keyword file
    # feol = FEOL corner (fs, tt, ss, etc.) for transistors, diodes
    # beol = BEOL corner (hl, tt, ll, etc.) for capacitors, resistors, inductors

    ordfiles = preferred_order(subfiles, feol)
    if debug:
        print('')
        print('Check_device:  Search order:')
        for ordfile in ordfiles:
            print('   ' + os.path.split(ordfile)[1])

    # Find the proper include file to include this device.  Attempt on all
    # entries in ordfiles, and stop at the first one that returns a result.
    # Assume that all files have unique names and point to the proper
    # location, so that is is only necessary to look at the last path
    # component.

    if debug:
        print('\nClimb hierarchy of includes to the top:')

    for ordfile in ordfiles:
        ordname = os.path.split(ordfile)[1]
        if debug:
            print('   (1) Search for "' + ordname  + '"')
        try:
            inclist = includedict[ordname][1:]
        except:
            if debug:
                print('   No include file found for "' + ordfile + '"')
                print('   Sample entry:')
                for key in includedict:
                    print('      ' + key + ': "' + str(includedict[key][1:]) + '"')
                    break
            continue
        else:
            if debug:
                print('   Starting list = ')
                for item in inclist:
                    print('      ' + item)

        while True:
            incfile = choose_preferred(inclist, feol, beol, notop, debug)
            incname = os.path.split(incfile)[1]
            if debug:
                print('   (2) Search for "' + incname  + '"')
            try:
                inclist = includedict[incname][1:]
            except:
                break
            else:
                if debug:
                    print('   Continuing list = ')
                    for item in inclist:
                        print('      ' + item)

        if debug:
            print('Final top level include file is: "' + incfile + '"')
        return incfile

    # Should only happen if subfiles is empty list
    return None

#-----------------------------------------------------------
# Find all cells and all models
#-----------------------------------------------------------

def find_everything(pathtop):
    cellspath = pathtop + '/cells'
    modelspath = pathtop + '/models'

    allcells = os.listdir(cellspath)

    subcktrex = re.compile('\.subckt[ \t]+([^ \t]+)[ \t]+', re.IGNORECASE)
    includerex = re.compile('\.include[ \t]+([^ \t]+)', re.IGNORECASE)

    filesdict  = {}
    subcktdict  = {}
    includedict  = {}
    modfilesdict  = {}

    for cellfile in allcells:
        cellpath = cellspath + '/' + cellfile
        cellfmts = os.listdir(cellpath)
        files_to_parse = []
        for cellfmt in cellfmts:
            fmtext = os.path.splitext(cellfmt)[1]
            if fmtext == '.spice':
                files_to_parse.append(cellpath + '/' + cellfmt)

        for file in files_to_parse:
            with open(file, 'r') as ifile:
                spicelines = ifile.read().splitlines()
                for line in spicelines:
                    smatch = subcktrex.match(line)
                    if smatch:
                        subname = smatch.group(1)
                        try:
                            subcktdict[subname].append(file)
                        except:
                            subcktdict[subname] = [file]
                        filetail = os.path.split(file)[1]
                        try:
                            filesdict[filetail].append(subname)
                        except:
                            filesdict[filetail] = [subname]

    files_to_parse = addmodels(modelspath)
    files_to_parse.extend(addmodels(cellspath))

    for file in files_to_parse:
        # NOTE:  Avoid problems with sonos directories using
        # "tt.spice", which causes the include chain recursive
        # loop to fail to exit.  This is a one-off exception
        # (hack alert)
        if '_of_life' in file:
            continue

        with open(file, 'r') as ifile:
            spicelines = ifile.read().splitlines()
            for line in spicelines:
                imatch = includerex.match(line)
                if imatch:
                    incname = imatch.group(1).strip('"')
                    inckey = os.path.split(incname)[1]

                    try:
                        inclist = includedict[inckey]
                    except:
                        includedict[inckey] = [incname, file]
                    else:
                        if file not in inclist[1:]:
                            includedict[inckey].append(file)
                    filetail = os.path.split(file)[1]
                    try:
                        modlist = modfilesdict[filetail]
                    except:
                        modfilesdict[filetail] = [incname]
                    else:
                        if incname not in modlist:
                            modfilesdict[filetail].append(incname)

    return filesdict, subcktdict, includedict, modfilesdict

#-----------------------------------------------------------
# Main application
#-----------------------------------------------------------

def do_find_all_devices(pathtop, sourcefile, cellname=None, feol='tt', beol='tt', doall=False, notop=False, debug=False):

    (filesdict, subcktdict, includedict, modfilesdict) = find_everything(pathtop)

    if sourcefile:
        # Parse the source file and find all 'X' records, and collect a list
        # of all primitive devices used in the file by cross-checking against
        # the dictionary of subcircuits.

        devrex = re.compile('x([^ \t]+)[ \t]+(.*)', re.IGNORECASE)
        incfiles = []

        with open(sourcefile, 'r') as ifile:
            spicelines = ifile.read().splitlines()

        if debug:
            print('Netlist file first line is "' + spicelines[0] + '"')

        isdev = False
        for line in spicelines:
            if line.startswith('*'):
                continue
            if line.strip() == '':
                continue
            elif line.startswith('+'):
                if isdev:
                    rest += line[1:]
            elif isdev:
                devname = get_device_name(rest)
                try:
                    subfiles = subcktdict[devname]
                except:
                    pass
                else:
                    incfile = check_device(subfiles, includedict, modfilesdict, feol, beol, notop, debug)
                    if not incfile:
                        incfile = preferred_order(subfiles, feol)[0]

                    if incfile:
                        if debug:
                            print('Device ' + devname + ':  Include ' + incfile)
                        if incfile not in incfiles:
                            incfiles.append(incfile)
                    else:
                        print('Something went dreadfully wrong with device "' + devname + '"')

                isdev = False
        
            smatch = devrex.match(line)
            if smatch:
                instname = smatch.group(1)
                rest = smatch.group(2)
                isdev = True
            elif isdev:
                devname = get_device_name(rest)
                try:
                    subfiles = subcktdict[devname]
                except:
                    pass
                else:
                    incfile = check_device(subfiles, includedict, modfilesdict, feol, beol, notop, debug)
                    if not incfile:
                        incfile = preferred_order(subfiles, feol)[0]

                    if incfile:
                        if debug:
                            print('Device "' + devname + '":  Include "' + incfile + '"')
                        if incfile not in incfiles:
                            incfiles.append(incfile)
                    else:
                        print('Something went dreadfully wrong with device "' + devname + '"')
                isdev = False

        # Return the .include lines needed
        return incfiles

    elif cellname:
        # Diagnostic:  Given a cell name on the command line (with -cell=<name>),
        # Run check_device() on the cell and report.
        try:
            subfiles = subcktdict[cellname]
        except:
            print('No cell "' + cellname + '" was found in the PDK files.')
            sys.exit(1)

        incfile = check_device(subfiles, includedict, modfilesdict, feol, beol, notop, debug)
        if debug:
            print('')
            print('Report:')
            print('')
            print('Cell = "' + cellname + '"')
            print('')

        bestfilepath = preferred_order(subfiles, feol)[0]
        if bestfilepath.startswith(pathtop):
            bestfile = bestfilepath[len(pathtop) + 1:]
        print('Subcircuit defined in (from ' + pathtop + '/): "' + bestfile + '"')

        if debug:
            print('')
            print('Top level include: ')

        if incfile:
            return [incfile]
        else:
            return [bestfilepath]

    elif doall:
        allincludes = []
        for cellname in subcktdict:

            # Diagnostic:  Given a cell name on the command line (with -cell=<name>),
            # Run check_device() on the cell and report.
            try:
                subfiles = subcktdict[cellname]
            except:
                print('No cell "' + cellname + '" was found in the PDK files.')
                continue

            incfile = check_device(subfiles, includedict, modfilesdict, feol, beol, notop, debug)
            print('Cell = "' + cellname + '"')
            bestfilepath = preferred_order(subfiles, feol)[0]
            if bestfilepath.startswith(pathtop):
                bestfile = bestfilepath[len(pathtop) + 1:]
            print('   Subcircuit: "' + os.path.split(bestfile)[1] + '"')
            print('   Include: ', end='')
            if incfile:
                if incfile not in allincludes:
                    allincludes.append(incfile)
                print('"' + incfile + '"')
            else:
                if bestfilepath not in allincludes:
                    allincludes.append(bestfilepath)
                print('"' + bestfilepath + '"')

        print('')
        print('Summary:  All files to include:\n')
        return allincludes

    else:
        # No source file given, so just dump the lists of subcircuits, models,
        # and files into four different output files.

        nsubs = 0
        with open('sublist.txt', 'w') as ofile:
            for key in subcktdict:
                nsubs += 1
                value = subcktdict[key]
                print(key + ': ' + ', '.join(value), file=ofile)

        nfiles = 0
        with open('filelist.txt', 'w') as ofile:
            for key in filesdict:
                nfiles += 1
                value = filesdict[key]
                print(key + ': ' + ', '.join(value), file=ofile)

        with open('inclist.txt', 'w') as ofile:
            for key in includedict:
                value = includedict[key]
                print(key + '(' + value[0] + '): ' + ', '.join(value[1:]), file=ofile)

        with open('modfilelist.txt', 'w') as ofile:
            for key in modfilesdict:
                value = modfilesdict[key]
                print(key + ': ' + ', '.join(value), file=ofile)

        print('Found ' + str(nsubs) + ' subcircuit definitions in ' + str(nfiles) + ' files.')
        return []

#-----------------------------------------------------------
# Command-line entry point
#-----------------------------------------------------------

if __name__ == "__main__":

    optionlist = []
    arguments = []

    for option in sys.argv[1:]:
        if option.find('-', 0) == 0:
            optionlist.append(option)
        else:
            arguments.append(option)

    # Defaults:  Set up for the most recent PDK version.
    version = 'v0.20.1'
    pathtop = '../../libraries/sky130_fd_pr/' + version
   
    # Default FEOL corner is "tt", and default BEOL corner is "tt"
    feol = 'tt'
    beol = 'tt'
    cellname = None
    debug = False
    doall = False
    notop = False

    # Override defaults from options

    for option in optionlist:
        if option.startswith('-version'):
            try:
                version = option.split('=')[1]
            except:
                print('Option usage:  -version=<versionstring>')
                sys.exit(1)
        elif option.startswith('-corner') or option.startswith('-feol'):
            try:
                feol = option.split('=')[1]
            except:
                print('Option usage:  -feol=<corner_name>')
                sys.exit(1)
        elif option.startswith('-beol'):
            try:
                beol = option.split('=')[1]
            except:
                print('Option usage:  -beol=<corner_name>')
                sys.exit(1)
        elif option.startswith('-cell'):
            try:
                cellname = option.split('=')[1]
            except:
                print('Option usage:  -cell=<cell_name>')
                sys.exit(1)
        elif option == '-notop':
            notop = True
        elif option == '-all':
            doall = True
        elif option == '-debug':
            debug = True

    # Parse "-pdkpath" after the others because it is dependent on any option
    # "-version" passed on the command line.

    for option in optionlist:
        if option.startswith('-pdkpath'):
            try:
                pathroot = option.split('=')[1]
            except:
                print('Option usage:  -pdkpath=<pathname>')
                sys.exit(1)
            if not os.path.isdir(pathroot):
                print('Cannot find PDK directory ' + pathroot)
                sys.exit(1)
            pathtop = pathroot + '/libraries/sky130_fd_pr/' + version
            if not os.path.isdir(pathtop):
                print('Cannot find primitive device directory ' + pathtop)
                sys.exit(1)

    # To be done:  Make this a useful routine that can insert one or more
    # .include statements into a SPICE netlist.  Should take any number of
    # files on the arguments line and modify the files in place.

    if len(arguments) > 0:
        sourcefile = arguments[0]
        if not os.path.isfile(sourcefile):
            print('Cannot read SPICE source file ' + sourcefile)
            sys.exit(1)
    else:
        sourcefile = None

    if not os.path.isdir(pathtop):
        print('Cannot find PDK path top level directory ' + pathtop)
        sys.exit(1)
    elif debug:
        print('\nFinding everything in ' + pathtop + '.')

    incfiles = do_find_all_devices(pathtop, sourcefile, cellname, feol, beol, doall, notop, debug)
    for incfile in incfiles:
        if incfile.endswith('.lib.spice'):
            print('.lib ' + incfile + ' ' + feol)
        else:
            print('.include "' + incfile + '"')

    sys.exit(0)
