#!/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 sys

import pygraphviz as pgv

import common

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 n(i):
    i = str(i)
    return '-'*(4-len(i))+'>'+i


number = {}
def indent(x, files):
    for pn in files:
        print('| '*x+'\-', end="")
        if pn not in includes:
            print("!", pn)
        elif pn in number:
            i = number[pn]
            print(n(i), pn)
            if includes[pn]:
                print('| '*(x+1)+'\----> ...', '(%d)'%i)
        else:
            i = len(number)
            number[pn] = i
            print(n(i), pn)
            indent(x+1, includes[pn])

print()
print("Top files")
print("-"*75)
for pn in top:
    number.clear()
    print()
    print(pn)
    indent(0, includes[pn])
print("-"*75)

version = common.version_extract_from_path(sys.argv.pop(1))
lib = sys.argv.pop(1)


G=pgv.AGraph(directed=True, overlap='false', splines='true')
G.node_attr.update(sep='0.1', constraint='false')
added = set()
def create_dot(g, src, files):
    for pn in files:
        if pn in added:
            continue
        else:
            added.add(pn)

        libname = common.lib_extract_from_path(pn)

        dirname, fname = os.path.split(pn)
        a, b = os.path.split(dirname)

        if libname:
            name = libname+'/'+fname
        else:
            name = fname
        print(pn, libname, name)

        attrs = {}
        if pn not in includes:
            attrs['bgcolor'] = 'red'

        g.add_node(name, **attrs)
        if src:
            g.add_edge(src, name)

        # Add children
        if pn in includes:
            create_dot(g, name, includes[pn])

has_includes = set()
for pn in top:
    if includes[pn]:
        has_includes.add(pn)

for i, pn in enumerate(sorted(has_includes)):

    v = common.version_extract_from_path(pn)
    libname = common.lib_extract_from_path(pn)
    if v != version:
        continue
    if libname != lib:
        continue

    print()
    print(pn)
    #g.graph_attr.update(bgcolor='red', )
    g = G.add_subgraph(name='cluster_%04d'%i)
    create_dot(g, None, [pn])

G.write("spice.includes.%s.%dv%dv%d.dot" % (lib, *version))
