#!/usr/bin/env python3
#
# insert_layer.py:  For the given install path, library name, and cellname,
# find the Magic layout of the cell, and add the specified layer geometry
# as given by a layer name and a string with four coordinate values.
# The layer is added to the layout in both the mag/ (full) and maglef/
# (abstract) directories.  Option "-maglef" or "-mag" will restrict the
# use to only the view indicated by the option.
#
# Extended 7/30/2023 to allow multiple rectangles to be specified by
# allowing any multiple of four coordinates.  So eight coordinates will
# generate two "rect" lines, for example.
# 
# e.g.:
#
# insert_layer.py /path/to/sky130A \
#	sky130_fd_io sky130_fd_sc_hd__a21bo_1 pwell "29 17 69 157" -mag

import os
import re
import sys

def addlayer(filename, layer, geometry):
    with open(filename, 'r') as ifile:
        magtext = ifile.read().splitlines() 

    layerrex = re.compile('<< ' + layer + ' >>')
    sectionrex = re.compile('<< ')
    labelsrex = re.compile('<< labels >>')
    propsrex = re.compile('<< properties >>')
    endrex = re.compile('<< end >>')

    in_layer = False
    done = False

    with open(filename, 'w') as ofile:
        for line in magtext:
            if not done and not in_layer:
                # Handle case in which layer did not already exist in file
                lmatch = labelsrex.match(line)
                pmatch = propsrex.match(line)
                ematch = endrex.match(line)
                if lmatch or pmatch or ematch:
                    print('<< ' + layer + ' >>', file=ofile)
                    for coords in zip(*[iter(geometry.split())]*4):
                        print('rect ' + ' '.join(coords), file=ofile)
                    done = True
            
            lmatch = layerrex.match(line)
            if lmatch or pmatch:
                in_layer = True
            elif in_layer:
                smatch = sectionrex.match(line)
                if smatch:
                    for coords in zip(*[iter(geometry.split())]*4):
                        print('rect ' + ' '.join(coords), file=ofile)
                    in_layer = False
                    done = True

            print(line, file=ofile)

def usage():
    print("insert_layer.py <path_to_pdk> <libname> <cellname> <layer> <geometry> [option]")
    print("  options:")
    print("   -mag      do only for the view in the mag/ directory")
    print("   -maglef   do only for the view in the maglef/ directory")
    return 0

if __name__ == '__main__':

    options = []
    arguments = []
    for item in sys.argv[1:]:
        if item.find('-', 0) == 0 and len(item) > 1 and item[1].isalpha():
            options.append(item)
        else:
            arguments.append(item)

    if len(arguments) < 5:
        print("Not enough arguments given to insert_layer.py.")
        usage()
        sys.exit(0)

    source = arguments[0]
    libname = arguments[1]
    cellname = arguments[2]
    layer = arguments[3]
    geometry = arguments[4]

    # Diagnostic
    print('insert_layer.py:')
    print('   source   = ' + source)
    print('   library  = ' + libname)
    print('   cell     = ' + cellname)
    print('   layer    = ' + layer)
    print('   geometry = ' + geometry)

    fail = 0

    efformat = True if '-ef_format' in options else False

    domag = True
    domaglef = True
    if '-mag' in options and '-maglef' not in options:
        domaglef = False
    if '-maglef' in options and '-mag' not in options:
        domag = False

    if domag:
        if efformat:
            filename = source + '/libs.ref/mag/' + libname + '/' + cellname + '.mag'
        else:
            filename = source + '/libs.ref/' + libname + '/mag/' + cellname + '.mag'

        if os.path.isfile(filename):
            addlayer(filename, layer, geometry)
        else:
            fail += 1
    else:
        fail += 1

    if domaglef:
        if efformat:
            filename = source + '/libs.ref/maglef/' + libname + '/' + cellname + '.mag'
        else:
            filename = source + '/libs.ref/' + libname + '/maglef/' + cellname + '.mag'

        if os.path.isfile(filename):
            addlayer(filename, layer, geometry)
        else:
            fail += 1
    else:
        fail += 1

    if fail == 2:
        print('Error:  No layout file in either mag/ or maglef/', file=sys.stderr)
        if efformat:
            print('(' + source + '/libs.ref/mag[lef]/' + libname +
		    '/' + cellname + '.mag)', file=sys.stderr)
        else:
            print('(' + source + '/libs.ref/' + libname + '/mag[lef]/'
		    + cellname + '.mag)', file=sys.stderr)

