#!/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 json
import os
import pprint
import sys

import common
import flatten

from spice import RE_SPICE_INC


includes = json.load(open(".files.includes.spice.json"))
rincludes = json.load(open(".files.rincludes.spice.json"))

top = set()
for includee in rincludes:
    if not rincludes[includee]:
        top.add(includee)
top = tuple(sorted(top))


def output_file(i, out, pn):
    dirname = os.path.split(pn)[0]
    for comment, bit in flatten.read_bits(pn, 'spice'):
        if comment:
            print(i, '-----\_________')
            print(bit.strip())
            print(i, '-----/^^^^^^^^^')
        else:
            for l in bit.splitlines(keepends=True):
                m = RE_SPICE_INC.match(l)
                if m:
                    out.flush()
                    incfile = m.group('inc')
                    incfn = os.path.realpath(os.path.join(dirname, incfile))
                    print(i, "Including", incfn)
                    out.write('// "')
                    out.write(incfn)
                    out.write('"\n')
                    output_file(i+'  ', out, incfn)
                else:
                    out.write(l)
    out.flush()


for pn in top:
    fname = os.path.split(pn)[-1]

    sim = {}
    sim['top'] = pn
    sim['version'] = common.version_extract_from_path(pn)
    sim['libnames'] = set()
    sim['modnames'] = set()
    sim['corner'] = None

    plibname, pmodname = common.mod_extract_from_path(pn)
    if plibname:
        assert '/' not in plibname, ("lib extract from path", plibname, pn)
        sim['libnames'].add(plibname)
    if pmodname:
        assert '/' not in pmodname, ("mod extract from path", pmodname, pn)
        sim['modnames'].add(pmodname)

    try:
        clibname, sim['corner'] = common.corners_extract_from_filename(fname)
        if clibname:
            assert '/' not in clibname, ("lib extract from corner", clibname, pn)
            sim['libnames'].add(clibname)

        if isinstance(sim['corner'], common.Corner):
            if sim['corner'].mod:
                sim['modnames'] = {sim['corner'].mod}
    except ValueError:
        pass

    print()
    pprint.pprint(sim)
    if not sim['libnames']:
        print(" Skipping - no lib name")
        continue
    elif len(sim['libnames']) > 1:
        print(" Skipping - multiple lib names")
        continue

    sim['oldlibname'] = list(sim['libnames'])[0].lower()
    sim['newlibname'] = common.convert_libname(sim['oldlibname'])

    if sim['version'] is None:
        print(" Skipping - no version")
        continue

    if not sim['modnames']:
        print(" Skipping - no module name")
        continue
    elif len(sim['modnames']) > 1:
        print(" Skipping - multiple module names")
        continue
    else:
        sim['modname'] = list(sim['modnames'])[0].lower()

    path = ['out', sim['newlibname'], "v%s.%s.%s" % sim['version'], 'sim', sim['modname']]
    if sim['corner'] and sim['corner'].extra:
        path[-1]+='_'+'_'.join(sim['corner'].extra)
    path[-1]+='.spice'

    print("", os.path.join(*path))

    basedir = os.path.join(*path[:-1])
    if not os.path.exists(basedir):
        os.makedirs(basedir)

    outn = os.path.join(*path)
    output_file('', open(outn, 'w'), pn)


