# Copyright 2022 GlobalFoundries 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
#
#      http://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.

"""
Run GlobalFoundries 180nm MCU DRC SC Regression.

Usage:
    run_sc_regression.py (--help| -h)
    run_sc_regression.py (--path=<file_path>)... [--thr=<thr>]

Options:
    --help -h                           Print this help message
    --path=<file_path>                  The input GDS file path.
    --thr=<thr>                         The number of threads used in run.

"""
from docopt import docopt
import os
import xml.etree.ElementTree as ET
import csv
import time
import concurrent.futures


def get_results(rule_deck_path, iname, file, x):
    """
    The function takes the path of the rule deck and the path of the gds file as inputs, then it runs
    the DRC using the rule deck on the gds file and returns the name of the gds file, the name of the
    rule deck, the names of the violated rules and the status of the gds file

    :param rule_deck_path: The path to the rule deck file
    :param path: The path to the GDS file you want to check
    :return: the file name, the rule deck name, the violated rules and the status of the file.
    """
    mytree = ET.parse(f"{iname[0]}_{x}.lyrdb")
    myroot = mytree.getroot()

    violated = []

    for lrule in rules:

        # Loop on database to get the violations of required rule
        for z in myroot[7]:
            if f"'{lrule}'" == f"{z[1].text}":
                violated.append(lrule)
                break

    if len(violated) > 0:
        status = "Not_clean"
    else:
        status = "Clean"

    rule_deck = rule_deck_path.split("../")

    print(f"\n The file {file[-1]} has violated rule deck {rule_deck[-1]} in: {len(violated)} rule/s which are: {violated} \n")
    print(f" The file {file[-1]} with rule deck {rule_deck[-1]} is {status} \n")
    return file[-1], rule_deck[-1], ' '.join(violated), status

def call_simulator(arg):
    """
    It runs the simulator with the given rule deck and input file, and saves the output to a database
    file

    :param rule_deck_path: The path to the rule deck file
    :param path: The path to the GDS file you want to simulate
    :param thrCount: number of threads to use
    """
    os.system(arg)

if __name__ == "__main__":

    t0 = time.time()
    args = docopt(__doc__)

    if os.path.exists("sc"):
        os.system("rm -rf sc")

    report = [["File_Name", "Rule Deck", "Rules", "Status"]]

    # Get threads count
    if args["--thr"]:
        thrCount = args["--thr"][0]
    else:
        thrCount = os.cpu_count() * 2

    os.system("klayout -v")

    rule_deck_path = []
    rules = []
    runs = []

    files = os.listdir('..')

    for file in files:
        if ".drc" in file:
            rule_deck_path.append(f"../{file}")

    # Get rules names
    for runset in rule_deck_path:
        with open(runset, 'r') as f:
            for line in f:
                if 'GEOMETRY RULES' in line:
                    break
                if ".output" in line:
                    line_list = line.split('"')
                    rules.append(line_list[1])

    # Create GDS splitter script
    with open('split_gds.rb', 'w') as f:
        f.write(''' layout = RBA::Layout::new
                    layout.read($input)
                    Dir.mkdir("sc") unless File.exists?("sc")

                    layout.each_cell do |cell|
                        ly2 = RBA::Layout.new
                        ly2.dbu = layout.dbu
                        cell_index = layout.cell_by_name("#{cell.name}")
                        new_top = ly2.add_cell("#{cell.name}")
                        ly2.cell(new_top).copy_tree(layout.cell("#{cell.name}"))
                        ly2.write("sc/#{cell.name}.gds")
                    end''')

    # Split standard cells top-cells into multiple gds files
    for path in args["--path"]:
        iname = path.split('.gds')
        file = iname[0].split('/')
        if "sc" in file[-1]:
            os.system(f"klayout -b -r split_gds.rb -rd input={path}")
            print(f"File {path} was splitted into multiple gds files")

    other_files = os.listdir('sc')
    args["--path"] = args["--path"] + other_files

    # Get input data for simulator
    for path in args["--path"]:
        x = 0
        iname = path.split('.gds')
        file = iname[0].split('/')
        if "sc" in file[-1]:
            continue
        if "/" not in path:
            path = f"sc/{path}"
        iname = path.split('.gds')
        file = iname[0].split('/')
        for runset in rule_deck_path:
            arg = f"klayout -b -r {runset} -rd input={path} -rd report={file[-1]}_{x}.lyrdb -rd thr={thrCount} -rd conn_drc=true"
            runs.append(arg)
            x += 1

    # Run DRC
    with concurrent.futures.ProcessPoolExecutor(max_workers=thrCount) as executor:
        for run in runs:
            executor.submit(call_simulator, run)

    # Get results
    for path in args["--path"]:
        x = 0
        iname = path.split('.gds')
        file = iname[0].split('/')
        if "sc" in file[-1]:
            continue
        if "/" not in path:
            path = f"sc/{path}"
        iname = path.split('.gds')
        file = iname[0].split('/')
        for runset in rule_deck_path:
            if os.path.exists(f"{iname[0]}_{x}.lyrdb"):
                file, rule_deck, violations, status = get_results(runset, iname, file, x)
                report.append([file, rule_deck, violations, status])
            x += 1

    with open(f'sc_drc_report.csv', 'w') as f:
        writer = csv.writer(f, delimiter=',')
        writer.writerows(report)

    if os.path.exists("split_gds.rb"):
        os.remove("split_gds.rb")

    if os.path.exists("sc"):
        os.system("rm -rf sc")

    t1 = time.time()
    print(f'Total execution time {t1 - t0} s')
