import argparse
from pathlib import Path
from collections import defaultdict
from pprint import pprint as pp
from os import system
import re


def extract_core_strength(filename):
        filecore = str(filename)[::-1].split('.', 2)[2][::-1]
        drivestrength = filecore[::-1].split('_', 1)[0][::-1]
        filecore = filecore[::-1].split('_', 1)[1][::-1]
        return filecore, drivestrength


if __name__ == '__main__':
    system("shopt -s globstar")
    parser = argparse.ArgumentParser()

    parser.add_argument(
        "input_dir",
        help="The path to the directory containing diagrams and schematics",
        type=Path)

    parser.add_argument(
        "--dry_run",
        help="Do not perform actions, only print the required actions",
        action='store_true')

    args = parser.parse_args()

    files = sorted(args.input_dir.rglob('*_[0-9].full.v'))

    print(len(files))

    groupedbydir = defaultdict(lambda: defaultdict(list))
    for i in files:
        filecore, drivestrength = extract_core_strength(i.name)
        groupedbydir[i.parent][filecore].append((drivestrength, i))

    for filesdir, filegroups in groupedbydir.items():
        for filecore, files in filegroups.items():
            allsame = True
            for i, strengthfil1 in enumerate(files):
                for strengthfil2 in files[i + 1:]:
                    with open(strengthfil1[1], 'r') as f1:
                        lines1 = f1.readlines()
                    with open(strengthfil2[1], 'r') as f2:
                        lines2 = f2.readlines()

                    if len(lines1) != len(lines2):
                        # print(f'NOl : {str(strengthfil1[1])} : {str(strengthfil2[1])}')
                        allsame = False
                        break
                    for line1, line2 in zip(lines1, lines2):
                        line1 = line1.replace(' ', '')
                        line2 = line2.replace(' ', '')
                        
                        if len(line1) != len(line2):
                            allsame = False
                        else:
                            for c1, c2, in zip(line1, line2):
                                if not (c1 == c2 or (c1 == strengthfil1[0] and c2 == strengthfil2[0])):
                                    allsame = False
                                    break
                        if not allsame:
                            break

                        # if 'module' in line1 and 'module' in line2:
                        #     converted = line1.replace(f'{strengthfil1[0]}', f'{strengthfil2[0]}')
                        #     if converted != line2:
                        #         # print(f'NOh : {str(strengthfil1[1])} : {str(strengthfil2[1])} {converted} {line2}')
                        #         allsame = False
                        #         break
                        # elif line1 != line2:
                        #     # print(f'NOd : {str(strengthfil1[1])} : {str(strengthfil2[1])} \n{line1} \n{line2}')
                        #     allsame = False
                        #     break
                if not allsame:
                    break
            if allsame:
                corewithstrengthregex = re.compile(
                    r'(?P<full>{}_(?P<strength>[0-9]+))'.format(filecore))
                filestomodify = filesdir.glob(f'{filecore}*')
                renamedtypes = set()
                for f in sorted(filestomodify):
                    print(f)
                    ftype = '.'.join(str(f).split('.')[-2:])
                    m = corewithstrengthregex.search(str(f))
                    if m:
                        if ftype not in renamedtypes:
                            toreplace = m.group('full')
                            print(f'toreplace: {toreplace}')
                            newname = Path(str(f).replace(toreplace, filecore))
                            if args.dry_run:
                                print(f'RENAME: {f} to {newname}')
                            else:
                                if f.suffix == '.v':
                                    with open(f, 'r') as old:
                                        with open(newname, 'w') as new:
                                            for line in old:
                                                rline = line.replace(toreplace, filecore)
                                                new.write(rline)
                                    f.unlink()
                                else:
                                    f.rename(newname)
                                # HACK, rewrite to python - replace all occurences of name with strength with basename
                                cells_dir = f.parents[1]
                                system(f" for x in `grep -r -l {toreplace} {cells_dir}`;do sed -i s/{toreplace}/{filecore}/g $x; done;")
                            renamedtypes.add(ftype)
                        else:
                            if args.dry_run:
                                print(f'REMOVE: {f}')
                            else:
                                f.unlink()
