#!/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 os
import json
from collections import defaultdict

import common

def module():
    return defaultdict(set)

def library():
    return defaultdict(module)


modules = defaultdict(library)

for p in os.listdir('.'):
    if not p.startswith('.files.mod2files.'):
        continue
    if not p.endswith('.json'):
        continue

    ftype = p[17:-5]
    data = json.load(open(p))

    for mod, files in data.items():
        libname, modname = common.lib_extract_from_name(mod)
        assert libname is None, (libname, modname, mod)
        assert modname is not None, (libname, modname, mod)

        for f in files:
            if 'rechar' in f:
                continue
            flibname, fmodname = common.mod_extract_from_path(f)
            if fmodname in ('pads', 'power_pads_lib', 'pads_routing', 'primdev', 's8_osu130'):
                fmodname = None
            if fmodname is None:
                fmodname = modname

            llibname = libname
            if llibname is None:
                llibname = flibname

            #if fmodname is not None and modname is not None:
            #    assert fmodname == modname, (
            #        ftype, ("file:", flibname, fmodname), f, ("origin:", libname, modname), mod)

            modules[modname][llibname][ftype].add(f)
            modules[modname]['all'][ftype].add(f)


for mod in sorted(modules):
    libs = list(modules[modname].keys())
    libs.remove('all')
    if None in libs:
        libs.remove(None)
    libs.sort()
    print("%-40s %-30s" % (modname, modules[modname].keys()))


all_files = set()
for mod in modules:

    # Write out a summary file for the module
    f = open(os.path.join('modules', mod+'.rst'), 'w')
    f.write('='*len(mod))
    f.write('\n')
    f.write(mod)
    f.write('\n')
    f.write('='*len(mod))
    f.write('\n')
    f.write('\n')
    libraries = list(modules[mod].keys())
    f.write('Found in:\n')
    for lib in libraries:
        if lib == 'all':
            continue
        lib = str(lib)
        f.write(' * ')
        f.write(lib)
        f.write('\n')

    f.write('\n')
    for lib in libraries:
        if lib == 'all':
            continue
        lib = str(lib)
        f.write(len(lib)*'-')
        f.write('\n')
        f.write(lib)
        f.write('\n')
        f.write(len(lib)*'-')
        f.write('\n')
        f.write('\n')

        for t in modules[mod][lib]:
            f.write(t)
            f.write('\n')
            f.write('+'*len(t))
            f.write('\n')
            f.write('\n')

            for fn in sorted(modules[mod][lib][t]):
                f.write(' - ')
                f.write(fn)
                f.write('\n')
            f.write('\n')
    f.close()

    # Write out a file list for the module
    for lib in libraries:
        files = set()
        for t in modules[mod][lib]:
            for fn in modules[mod][lib][t]:
                files.add(fn)

        libdir = os.path.join('modules', str(lib))
        if not os.path.exists(libdir):
            os.makedirs(libdir)

        with open(os.path.join(libdir, mod+'.files'), 'w') as f:
            for fn in sorted(files):
                f.write(fn)
                f.write('\n')

    print()
    print(mod, end='')
    libraries = list(modules[mod].keys()) #list(x for x in modules[mod].keys() if x is not None)
    if len(libraries) > 0:
        print(" in", libraries)
    else:
        print()
    print("="*75)
    files = defaultdict(set)

    for l in modules[mod]:
        lib = modules[mod][l]
        if l is not None:
            print("In lib", l, "has", end=" ")
        else:
            print("Has", end=" ")
        print(list(lib.keys()), "files")
        for t in lib:
            for f in lib[t]:
                files[t].add(f)

    for t in sorted(files):
        if t == 'files':
            continue
        print()
        print(t)
        print('-'*5)
        for f in sorted(files[t]):
            all_files.add(f)
            print(f)

    def in_other(f):
        for t in files:
            if t == 'files':
                continue
            if f in files[t]:
                return True
        return False

    if 'files' in files:
        print()
        print("Other files")
        print('-'*5)
        for f in sorted(files['files']):
            if in_other(f):
                continue
            else:
                print(f)

print()
print()
print("Remaining unexamined files")
print("="*75)
with open('.files.unused', 'w') as f:
    for fn in common.files([]):
        if fn in all_files:
            continue
        print(fn)
        f.write(fn)
        f.write('\n')
