#!/usr/bin/env python3

import csv
import os
import pprint
import re
import sys

from collections import defaultdict

import common
import flatten
import argparse
from pathlib import Path


RE_MODEL_START = re.compile(r'^model\s+(?P<model>[^ ]+)\s+bsim(?P<bsim>[0-9vV]+)\s+{(\n|$)')
RE_MODEL_END = re.compile(r'^[\s\n]*ends(?P<end>.*)(\n|$)')
RE_ROW = re.compile(r'^\s*(?P<row>[0-9]+):\s*type=(?P<type>.*?)(\n|$)')
RE_PARAM = re.compile(r'^[+]\s*(?P<param>[^ ]+)\s*=\s*(?P<value>.+?)(\n|$)')
RE_GROUP = re.compile(r'[*\s]*?(?P<group>[^*\n]+?)[*\s]*(\n|$)')

GROUPS = defaultdict(set)
FIELDS = set()

def write_csv(outname, models):
    w = csv.writer(open(outname,'w'))

    row = ['model', 'bin', 'num_bins']
    row.extend(sorted(FIELDS))
    w.writerow(row)

    for m in models:
        for i, r in enumerate(m['rows']):
            row = []
            row.append(m['model'])
            row.append(i)
            row.append(len(m['rows']))
            for f in sorted(FIELDS):
                row.append(r.get(f, 'N\A'))
            w.writerow(row)


def pm3_to_rows(infile):
    models = [None]

    rows = []
    row_params = {}
    group = None
    for comment, bit in flatten.read_bits(infile, 'spice'):
        if comment:
            m = RE_GROUP.match(bit)
            if m:
                group = m.group('group').title()
                print('g', group)
            else:
                print('#', repr(bit))
        else:
            for l in bit.splitlines(keepends=True):
                if models[-1] is None:
                    m = RE_MODEL_START.match(l)
                    if not m:
                        print("Skipping", repr(l))
                        continue
                    models.pop(-1)
                    models.append({
                        'model': m.group('model'),
                        'bsim': m.group('bsim'),
                        'rows': [],
                    })
                    continue

                m = RE_MODEL_END.match(l)
                if m:
                    if row_params:
                        models[-1]['rows'].append(row_params)
                    print("Ends", m.group('end'))
                    models.append(None)
                    break

                m = RE_ROW.match(l)
                if m:
                    if row_params:
                        models[-1]['rows'].append(row_params)
                    row = m.group('row')
                    t = m.group('type')
                    row_params = {
                        'row': 0,
                        'type': t,
                    }
                    continue

                m = RE_PARAM.match(l)
                if m:
                    params = {}

                    name = [m.group('param')]
                    value = []
                    bits = m.group('value').split()
                    print(name, bits)
                    while bits:
                        value.append(bits.pop(0))
                        if bits and bits[0] in ('+', '*'):
                            value.append(bits.pop(0))
                            value.append(bits.pop(0))

                        if value[-1][-1] == '(':
                            value.append(bits.pop(0))
                            continue

                        params["".join(name)] = " ".join(value)
                        if bits:
                            name = [bits.pop(0)]
                            value = []
                            assert bits.pop(0) == '=', repr(l)
                    print(params)
                    for k in params:
                        FIELDS.add(k)
                        GROUPS[group].add(k)
                        assert k not in row_params
                        try:
                            params[k] = float(params[k])
                        except ValueError:
                            pass
                        row_params[k] = params[k]

                    continue

                if l.strip():
                    print('?', repr(l))


    assert models[-1] == None
    models.pop(-1)
    return models


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "input_dir",
        help="The path to the directory containing skywater-pdk",
        type=Path)

    parser.add_argument(
        "--dry-run",
        help="Do not perform actions on filesystem, only print",
        action="store_true")

    args = parser.parse_args()

    files = sorted(args.input_dir.rglob('*.pm3'))

    print(len(files))

    models = []
    for pn in files:
        pn = str(pn)
        if 'rf' in pn:
            continue
        print()
        print(pn)
        print('='*75)
        newmodels = pm3_to_rows(pn)
        base, ext = os.path.splitext(pn)
        print('-'*75)
        outfile = base+'.csv'
        print(outfile)
        # write_csv(outfile, newmodels)
        print(newmodels)
        print('='*75)
        models.extend(newmodels)


    write_csv('out.csv', models)

    sys.exit(1)

    # Header 1
    #row = ['',]
    #for h1 in sorted(groups):
    #    row.append(h1)
    #    row.extend(['']*(len(groups[h1])-1))
    #csv_rows.append(row)

    # Header 2
    row = ['type',]
    #h2toh1 = {}
    for h1 in sorted(groups):
        for h2 in sorted(groups[h1]):
            row.append(h2)
            h2toh1[h2] = h1
    csv_rows.append(row)

    for row in rows:
        csv_rows.append([row['type'],])
        for h2 in csv_rows[1][1:]:
            h1 = h2toh1[h2]
            csv_rows[-1].append(row[h1].get(h2,'N/A'))

    w.writerows(csv_rows)
