import argparse
import re
from pathlib import Path
import json
from termcolor import colored
from collections import defaultdict, deque
from pprint import pprint as pp
import common
import os
from pathlib import Path
import shlex


copyright = [
    '* Copyright 2019 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.',
    ''
]


def get_relative_path_to(path_from: Path, path_to: Path):
    path_from = Path(path_from)
    path_to = Path(path_to)
    absolute_from = os.path.abspath(path_from.parent)
    absolute_to = os.path.abspath(path_to)
    relpath = os.path.relpath(absolute_to, absolute_from)
    print(str(absolute_from))
    print(str(absolute_to))
    print(str(relpath))
    return relpath

def basic_cleaning(lines):
    fullfile = '\n'.join(lines)
    # remove comments (C/C++ style)
    fullfile = re.sub(r'(?:\/\*(.*?)\*\/)', '',
                      fullfile, flags=re.DOTALL)

    # replace all tabs with single space
    fullfile = fullfile.replace('\t', ' ')

    lines = fullfile.split('\n')

    lines = [line.rstrip() for line in lines if line.strip()]
    finlines = []
    for line in lines:
        line = re.sub(r'\/\/.*$', '', line)
        if not line:
            continue
        if re.match(r'^\s*\*.*$', line):
            continue
        finlines.append(line)
    return finlines

def remap_path(old_path, ext, base = "output/skywater-pdk/libraries", modname=None):
    lib, mod = common.mod_extract_from_path(old_path)
    if common.version_extract_from_path(old_path):
        ver = "V" + ".".join([str(v) for v in common.version_extract_from_path(old_path)])
    else:
        ver = ''
    if lib is not None and lib != '???':
        if modname is not None:
            mod = modname
        elif mod is None and lib is not None:
            mod = lib
        rest, f_name= os.path.split(old_path)
        if f_name == "verilog.v":
            if rest.split('/')[-2] != 'skywater-src-nda':
                d_name = f"{rest.split('/')[-2]}_{rest.split('/')[-1]}"
            else:
                d_name = rest.split('/')[-1]
        else:
            if modname == 'broken':
                d_name = f"{rest.split('/')[-3]}_{rest.split('/')[-2]}"
                if lib == 's8phirs_10r':
                    d_name += '_10r'
            else:
                if rest.split('/')[-2] != 'skywater-src-nda':
                    d_name = f"{rest.split('/')[-2]}_{rest.split('/')[-1]}"
                else:
                    d_name = rest.split('/')[-1]
        # remove Models/SPECTRE names from final path
        brokendir = '' if modname != 'broken' else 'broken'
        finfilename = f'{d_name}_{Path(f_name).stem}_{mod}{ext}'
        finfilename = finfilename.replace('Models_', '')
        finfilename = finfilename.replace('SPECTRE_', '')
        old_path = Path(base) / brokendir / lib / ver / 'cells' / re.sub(r'_[0-9]$', '', mod) / finfilename
    else:
        index = old_path.find('skywater-src-nda') + len('skywater-src-nda')
        old_path = Path(base) / ('./' + old_path[index:])
    old_path = str(old_path).replace("/s8iom0s8/", "/sky130_fd_io/")
    old_path = str(old_path).replace("/s8/", "/sky130_fd_pr/")
    old_path = old_path.replace("/VirtuosoOA/libs", "")
    new_lib = None if lib is None else common.convert_libname(lib)
    if  lib != None and new_lib != None:
        new_path = old_path.replace(lib, new_lib)
    else:
        new_path = old_path
    return new_path

def makefixedwidthcolumn(spicelines):
    lastnumcol = -1
    columngroup = []
    result = []
    mergeequalsign = re.compile(r'\s*=')
    startpluswithspace = re.compile(r'^\+\s*')
    for line in spicelines + ['']:
        line = mergeequalsign.sub('=', line)
        line = startpluswithspace.sub('+', line)
        columns = shlex.split(line, posix=False)
        for i in range(len(columns)):
            columns[i] = ' '.join(columns[i].split())
        dump = False
        if lastnumcol == -1 and len(columns) != 0:
            lastnumcol = len(columns)
            columngroup.append(columns)
        elif len(columns) == 0 or lastnumcol == len(columns):
            columngroup.append(columns)
        else:
            dump = True
        if dump:
            columnwidths = [max([len(val) for val in [row[i] for row in columngroup if len(row) == lastnumcol]]) for i in range(lastnumcol)]
            for row in columngroup:
                res = ' '.join([row[i].ljust(columnwidths[i]) for i in range(lastnumcol) if len(row) == lastnumcol])
                result.append(res.rstrip())
            result.append('')
            columngroup = []
            lastnumcol = -1
            if len(columns) > 0:
                columngroup.append(columns)
                lastnumcol = len(columns)
    if len(columngroup) > 0:
        columnwidths = [max([len(val) for val in [row[i] for row in columngroup if len(row) == lastnumcol]]) for i in range(lastnumcol)]
        for row in columngroup:
            res = ' '.join([row[i].ljust(columnwidths[i]) for i in range(lastnumcol) if len(row) == lastnumcol])
            result.append(res.rstrip())
    return result
   

def cleanspicefile(spicelines, cellname, filepath, newfilepath, oldlibname, newlibname, includemaps):
    cleanedspicelines = []

    filedir = Path(filepath).parent

    spicelines = basic_cleaning(spicelines)

    for line in spicelines:
        if 'include' in line:
            match = re.search(r'.*include\s*[\"\']?(?P<includename>[^\"\']+)[\"\']?', line)
            includecontent = match.group('includename')
            originalpath = os.path.abspath(filedir / includecontent)
            if not os.path.exists(originalpath):
                raise Exception(f'File not found:  {originalpath}')
            else:
                if 'ahdl_include' in line:
                    with open(originalpath, 'r') as verilogafile:
                        verilogalines = verilogafile.readlines()
                        verilogalines = basic_cleaning(verilogalines)
                        newverilogapath = Path(newfilepath).parent / Path(originalpath).name
                        verilogalines = [l.replace('*','//') for l in copyright] + verilogalines
                        with open(newverilogapath, 'w') as newverilogafile:
                            newverilogafile.write('\n'.join(verilogalines))
                        includemaps[os.path.abspath(originalpath)] = os.path.abspath(newverilogapath)
                elif not originalpath in includemaps:
                    return None
                relpath = Path(get_relative_path_to(newfilepath, includemaps[originalpath]))
                if not os.path.exists(includemaps[originalpath]):
                    raise Exception('File not found {} : {}'.format(includemaps[originalpath]))
                if not re.search(r'[\"\']?{}[\"\']?'.format(re.escape(includecontent)), line):
                    raise Exception('FAILED TO FIND {}'.format(r'[\"\']?{}[\"\']?'.format(re.escape(includecontent))))
                line = re.sub(r'[\"\']?{}[\"\']?'.format(re.escape(includecontent)), '"' + str(relpath) + '"', line)
                cleanedspicelines.append(line)
        else:
            line = line.replace(oldlibname, newlibname)
            cleanedspicelines.append(line)
    fixedcolumns = makefixedwidthcolumn(cleanedspicelines)
    return fixedcolumns

if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    parser.add_argument(
        'input',
        help='Input JSON file containing the product of spice2mods.py script',
        type=Path)
    parser.add_argument(
        'outputdir',
        help='Directory containing cleaned Spice sources',
        type=Path)
    parser.add_argument(
        "--path-prefix-to-remove",
        help="The substring that needs to be removed before generating subdirectories for Liberty files",
        type=Path)

    args = parser.parse_args()

    with open(args.input, 'r') as infile:
        celltolibs = json.load(infile)

    containingcellnames = defaultdict(list)

    # this is sorted so always the longest matching string will be taken
    cellnames = sorted(list(celltolibs.keys()), key=lambda i: (-len(i),i))

    for i, cell in enumerate(cellnames):

        for cell2 in cellnames[i + 1:]:
            if cell in cell2:
                containingcellnames[cell].append(cell2)
            elif cell2 in cell:
                containingcellnames[cell2].append(cell)

    toprocess = []

    for cell, files in celltolibs.items():
        celldir = args.outputdir / cell
        # celldir.mkdir(parents=True, exist_ok=True)
        for f in files:
            try:
                oldlibname = common.lib_extract_from_path(str(f))
            except Exception as ex:
                print(f)
                print(ex)
            if not oldlibname or oldlibname == '???':
                oldlibname = None
                newlibname = None
            else:
                newlibname = common.convert_libname(oldlibname)
            # newf = f.replace(oldlibname, newlibname) if oldlibname else f
            ext = Path(f).suffix
            newf = remap_path(f, ext, base=args.outputdir, modname=cell)
            # dirprefix = str(Path(f).parent)
            # if args.path_prefix_to_remove:
            #     dirprefix = dirprefix.replace(str(args.path_prefix_to_remove), '')
            # dirprefix = dirprefix.replace(oldlibname, newlibname) if oldlibname else f
            # target = findir / Path(newf).name
            toprocess.append((f, cell, newf, oldlibname, newlibname, False))

    newfiles = {}
    repeated = False
    for data in toprocess:
        if data[2] in newfiles:
            repeated = True
            print(f'This file will be overwritten: {(data[1], data[0])} = {newfiles[data[2]]}')
            print(f'{data[2]}')
        else:
            newfiles[data[2]] = (data[1], data[0])

    assert not repeated

    allfilescount = len(toprocess)

    numfailed = 0

    errortypes = set()

    taskqueue = deque(toprocess)

    num = 0

    includemaps = {}

    while taskqueue:
        data = taskqueue.popleft()
        try:
            filename, cell, newfilename, oldlibname, newlibname, done = data
            newfilename = Path(newfilename)
            with open(filename, 'r') as f:
                spicelines = f.readlines()
            if not os.path.isdir(newfilename.parent):
                newfilename.parent.mkdir(parents=True, exist_ok=True)
            cleanedfile = cleanspicefile(spicelines, cell, filename, newfilename, oldlibname, newlibname, includemaps)
            if cleanedfile:
                with open(newfilename, 'w') as outputspice:
                    fin = copyright + cleanedfile
                    outputspice.write('\n'.join(fin))
                includemaps[os.path.abspath(filename)] = os.path.abspath(newfilename)
                print(colored('[{:05d}/{:05d},failed={:05d}] {} : {} | {}DONE'.format(num + 1, allfilescount, numfailed, cell, filename, 'RESOLVED AND ' if done else ''), 'green'))
                num += 1
            else:
                taskqueue.append((filename, cell, newfilename, oldlibname, newlibname, True))
                print(colored('[{:05d}/{:05d},failed={:05d}] {} : {} | INCLUDES NOT RESOLVED YET'.format(num + 1, allfilescount, numfailed, cell, filename), 'yellow'))
        except Exception as ex:
            print(colored('[{:05d}/{:05d},failed={:05d}] {} : {} | ERROR : {}'.format(num + 1, allfilescount, numfailed, cell, filename, str(ex)), 'red'))
            errortypes.add(type(ex).__name__)
            num += 1
            numfailed += 1
    print('{} out of {} failed'.format(numfailed, allfilescount))
    print('Error types:')
    print(errortypes)
