#!/usr/bin/env python3

import json
import os
import pprint
import re

from collections import defaultdict

import common
from spice import RE_SPICE_INC

"""
* RF MOS PARAMETERS
.inc "nshort_rf_base_b_tt_leak.cor"
.inc "nlowvt_rf_base_b_tt_leak.cor"
.inc "nhv_rf_base_b_tt_leak.cor"
.inc "pshort_rf_base_b_tt_leak.cor"
.inc "nshort_rf_mm.cor"
.inc "nlowvt_rf_mm.cor"
.inc "nhv_rf_mm.cor"
.inc "pshort_rf_mm.cor"
.inc "pmedlvt_rf_ttleak_discrete.cor"
.inc "pmedlvt_rf_mm.cor"
"""

includes = {}
include_files = defaultdict(set)

for pn in common.files('spice'):
    _, ext = os.path.splitext(pn)

    cmts = [('*', '//'), [('/*','*/')]]

    includes[pn] = set()
    basedir = os.path.split(pn)[0]

    print("--", "Reading -->", pn)
    for line in common.read_without_cmts(pn, cmts):
        m = RE_SPICE_INC.match(line)
        if not m:
            continue
            print(line)
        else:
            fullname = os.path.realpath(os.path.join(basedir, m.group("inc")))
            _, ext = os.path.splitext(fullname)
            if os.path.exists(fullname):
                print(ext, "      Found", fullname)
            else:
                print(ext, "*Not* Found", fullname)

            includes[pn].add(fullname)

# Save the include graph
for inculder in includes:
    includes[inculder] = tuple(sorted(includes[inculder]))
json.dump(includes, open(".files.includes.spice.json", "w"), sort_keys=True, indent=2)

# Work out any missing includes
missing = set()
for inculder in includes:
    for includee in includes[inculder]:
        if includee not in includes:
            missing.add(includee)

with open(".files.includes.spice.missing", "w") as f:
    for pn in sorted(missing):
        f.write(pn)
        f.write("\n")

# Build a reverse include (dependency) map
rincludes = defaultdict(set)
for includer in includes:
    rincludes[includer].add(None)
    for includee in includes[includer]:
        rincludes[includee].add(includer)

for includee in rincludes:
    rincludes[includee] = tuple(sorted(x for x in rincludes[includee] if x is not None))
json.dump(rincludes, open(".files.rincludes.spice.json", "w"), sort_keys=True, indent=2)

print()
if missing:
    print("Missing?")
    print("-"*75)
    for pn in sorted(missing):
        if not os.path.exists(pn):
            print(" ", end="")
        else:
            print(">", end="")
        print(pn)
    print("-"*75)
else:
    print("No missing includes!")
