#!/usr/bin/env python3
# Copyright 2020 The Skywater PDK Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


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)

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

    pprint.pprint(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)
