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):
    core = str(filename.parent).split('/')[-1]
    assert core in filename.name, (core, filename.name)
    filewithoutext = str(filename.name).replace('.full.v', '')
    if not filewithoutext.endswith(core):
        drivestrength = filewithoutext[::-1].split('_', 1)[0][::-1]
        filewithoutext = filewithoutext[::-1].split('_', 1)[1][::-1]
        return filewithoutext, drivestrength
    else:
        return filewithoutext, None

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)
        if drivestrength is not None:
            groupedbydir[i.parent][filecore].append((drivestrength, i))

    pp(groupedbydir)

    for filesdir, filegroups in groupedbydir.items():
        for filecore, files in filegroups.items():
            allsame = True
            print(files)
            if len(files) >= 1:
                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
                            print(f'Different number of lines: {len(lines1)} != {len(lines2)}')
                            print(f'Different number of lines: {strengthfil1[1]} != {strengthfil2[1]}')
                            break
                        for line1, line2 in zip(lines1, lines2):
                            line1 = line1.replace(' ', '').strip()
                            line2 = line2.replace(' ', '').strip()
                            
                            if line1.startswith('module') and line2.startswith('module'):
                                split1 = line1.split('(')[0].split('_')
                                converted = '_'.join(split1[:-1] + [strengthfil2[0]])
                                if converted != line2.split('(')[0]:
                                    # print(f'NOh : {str(strengthfil1[1])} : {str(strengthfil2[1])} {converted} {line2}')
                                    print(f'Invalid module {converted} {line2}')
                                    allsame = False
                                    break
                            elif line1 != line2:
                                if len(line1) != len(line2):
                                    print(f'Length of lines differ:\n{line1}\n{line2}')
                                    allsame = False
                                    break
                                if line1 != line2:
                                    for c1, c2, in zip(line1, line2):
                                        if c1 != c2:
                                            if c1 != strengthfil1[0] and c2 != strengthfil2[0]:
                                                print(f'Differ: {line1} != {line2}')
                                                print(f'Differ: {strengthfil1[0]} != {c1}')
                                                print(f'Differ: {strengthfil2[0]} != {c2}')
                                                allsame = False
                                                break
                                if not allsame:
                                    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:
                                    print(f'RENAME: {f} to {newname}')
                                    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} --exclude=*.lib`;do sed -i s/{toreplace}/{filecore}/g $x; done;")
                                renamedtypes.add(ftype)
                            else:
                                if args.dry_run:
                                    print(f'REMOVE: {f}')
                                else:
                                    print(f'REMOVE: {f}')
                                    f.unlink()
