#!/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 argparse
import os
import re
import subprocess
import json
from collections import defaultdict
from pathlib import Path
from common import lib_extract_from_path, version_extract_from_path, convert_libname

sourcetodests = defaultdict(list)

Copyright_header = ('# Copyright 2020 The Skywater PDK Authors\n'
    '#\n'
    '# Licensed under the Apache License, Version 2.0 (the "License");\n'
    '# you may not use this file except in compliance with the License.\n'
    '# You may obtain a copy of the License at\n'
    '#\n'
    '#     https://www.apache.org/licenses/LICENSE-2.0\n'
    '#\n'
    '# Unless required by applicable law or agreed to in writing, software\n'
    '# distributed under the License is distributed on an "AS IS" BASIS,\n'
    '# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n'
    '# See the License for the specific language governing permissions and\n'
    '# limitations under the License.\n'
    '\n')

def remap_path(old_path, input_dir, output_dir, lib_name, new_lib_name):
    """
    >>> remap_path('Dokumenty/SkyWater/skywater-src-nda/scs8hd/V0.0.1/lef/scs8hd.lef', 'Dokumenty/SkyWater/skywater-src-nda' ,'output', 'scs8hd', 'sky130_fd_sc_hd')
    'output/skywater-pdk/libraries/sky130_fd_sc_hd/V0.0.1/sky130_fd_sc_hd.lef'
    >>> remap_path('Dokumenty/SkyWater/skywater-src-nda/s8iom0s8/V0.1.0/lef/s8iom0s8.lef', 'Dokumenty/SkyWater/skywater-src-nda' ,'output', 's8iom0s8', 'sky130_fd_io')
    'output/skywater-pdk/libraries/sky130_fd_io/V0.1.0/sky130_fd_io.lef'
    >>> remap_path('Dokumenty/SkyWater/skywater-src-nda/s8fmlt/V0.1.0/lef/s8fmlt__16k_sys.lef', 'Dokumenty/SkyWater/skywater-src-nda' ,'output', 's8fmlt', 'sky130_fd_fmlt')
    'output/skywater-pdk/libraries/sky130_fd_fmlt/V0.1.0/sky130_fd_fmlt__16k_sys.lef'
    """
    parent_dir = str(input_dir).split("/")[-1]
    output_dir = str(output_dir)

    index = old_path.find(parent_dir) + len(parent_dir)

    target_dir, target_file = os.path.split(old_path[index:])
    if len(target_file.split('.')[0]) > len(lib_name):
        target_file = target_file[:len(lib_name)] + '_' + target_file[len(lib_name)+1:]
    new_path = output_dir +"/skywater-pdk/libraries" + target_dir.replace("/lef","") + "/"  + target_file

    assert lib_name != None and new_lib_name != None
    new_path = new_path.replace(lib_name, new_lib_name)

    return new_path

def rewrite_lef(lef_file, out_file):
    lef_file = os.path.abspath(lef_file)
    p = subprocess.Popen(['lefrw', '-o', out_file , lef_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout , stderr = p.communicate()
    ret = p.wait()
    if stderr != b'':
        print(stderr)
    return ret

def change_naming(contents, libi, new_lib_name):
    assert new_lib_name != None
    contents = contents.replace(lib + '_', new_lib_name + '__')

    return contents, new_lib_name

def main(lef_file, lib_name, new_lib_name, out_file=None):

    rewrite_lef(lef_file, 'temp.lef')
    with open('temp.lef') as in_f:
        contents = in_f.read()
    out, _ = change_naming(contents, lib_name, new_lib_name)
    out = re.sub(r"Parsed [0-9]* number of lines!![\n]", "", out)
    out = re.sub(r"MACRO\s+CLASS\s+[A-Z ]*[\n]", "", out)
    out = re.sub(r"DIVIDER (?P<div>.) ;", "DIVIDERCHAR \"\g<div>\" ;", out)
    out.replace(Copyright_header, '')
    out = Copyright_header + out

    if out_file is not None:
        dest_dir =  os.path.split(out_file)[0]
        if not os.path.isdir(dest_dir):
            os.makedirs(dest_dir)
        with open(out_file, 'w') as out_f:
            out_f.write(out)
    else:
        pass
        print(">>> Output:\n"+"_"*60+ "\n" + out)

if __name__ == "__main__":
    import doctest
    fails, _ = doctest.testmod()
    if fails>0:
        exit()
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "input",
        help="The path to the source directory/file",
        type=Path)
    parser.add_argument(
        "output",
        help="The path to the output directory",
        type=Path)
    parser.add_argument(
        "sourcetodests",
        help="output file mapping input to output",
        type=Path)
    args = parser.parse_args()
    if not os.path.isdir(args.input):
        lib = lib_extract_from_path(args.input)
        new_lib = convert_libname(lib)
        debug = True
        main(str(args.input), lib, new_lib)
    else:
        files = sorted(args.input.rglob('*.lef'))
        for f in files:
            f = str(f)
            if '/s8/' in f or 's8iom0s8' in f or 'sram' in f or 'osu130' in f or 's8iom0s8' in f or 's8fmlt' in f:
                continue

            print(f)
            lib = lib_extract_from_path(f)
            print(lib)
            new_lib = convert_libname(lib)
            out_f = remap_path(f, args.input, args.output, lib, new_lib)
            sourcetodests[f].append(out_f)
            main(f, lib, new_lib, out_f)
    os.remove('temp.lef')
    with open(args.sourcetodests, 'w') as srctodest:
        json.dump(sourcetodests, srctodest, indent=2)

