import json
import argparse
from pathlib import Path
import os
import re

def list_nonzero(data, origkey=None):
    result = []
    if type(data) in [str, int, float]:
        try:
            val = float(data)
            if val != 0:
                result.append((origkey,val))
            else:
                return result
        except:
            return result
    elif type(data) == list:
        for val in data:
            result.extend(list_nonzero(val, origkey))
        return result
    elif type(data) == dict:
        for key, val in data.items():
            result.extend(list_nonzero(val, key))
        return result
    else:
        raise Exception(f'Unsupported type:  {type(data)}')
    return result

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "input_dir",
        help="Directory containing Liberty files",
        type=Path)

    args = parser.parse_args()
    
    files = sorted(args.input_dir.rglob('*.specify.json'))

    for f in files:
        print(f'====> {f}')
        with open(f, 'r') as dat:
            data = json.load(dat)
        nonzerovalues = sorted(list(set(list_nonzero(data))))
        par = f.parent
        for val in nonzerovalues:
            # os.system(f'rg "\\"{re.escape(str(float(val)))}\\"" {par} --glob "*cell.json"')
            print(f'PARAM {val[0]} = {val[1]}')
            # os.system(f'rg " : {re.escape(str(float(val[1])))};" {par} --glob "*cell.lib" -NI | sort | uniq -c')
            os.system(f'grep -r --no-filename " : {re.escape(str(float(val[1])))}" --include \*.cell.lib --include \*.wrap.lib {par} | sort | uniq -c')
