# 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 IC LVS.

Usage:
    run_lvs.py (--help| -h)
    run_lvs.py (--design=<layout_path>) (--net=<netlist_path>) (--gf180ic=<combined_options>) [--thr=<thr>] [--run_mode=<run_mode>] [--lvs_sub=<sub_name>] [--no_net_names] [--set_spice_comments] [--set_scale] [--set_verbose] [--set_schematic_simplify] [--set_net_only] [--set_top_lvl_pins] [--set_combine] [--set_purge] [--set_purge_nets]

Options:
    --help -h                           Print this help message.
    --design=<layout_path>              The input GDS file path.
    --net=<netlist_path>                The input netlist file path.
    --gf180ic=<combined_options>       Select combined options of metal_top, mim_option, and metal_level. Allowed values (A, B, C).
                                        gf180ic=A: Select  metal_top=30K  mim_option=A  metal_level=3LM  poly_res=1K, and mim_cap=2
                                        gf180ic=B: Select  metal_top=11K  mim_option=B  metal_level=4LM  poly_res=1K, and mim_cap=2
                                        gf180ic=C: Select  metal_top=9K   mim_option=B  metal_level=5LM  poly_res=1K, and mim_cap=2
    --thr=<thr>                         Number of cores to be used by LVS checker
    --run_mode=<run_mode>               Select klayout mode Allowed modes (flat , deep, tiling). [default: deep]
    --lvs_sub=<sub_name>                Assign the substrate name used in design.
    --no_net_names                      Discard net names in extracted netlist.
    --set_spice_comments                Set netlist comments in extracted netlist.
    --set_scale                         Set scale of 1e6 in extracted netlist.
    --set_verbose                       Set verbose mode.
    --set_schematic_simplify            Set schematic simplification in input netlist.
    --set_net_only                      Set netlist object creation only in extracted netlist.
    --set_top_lvl_pins                  Set top level pins only in extracted netlist.
    --set_combine                       Set netlist combine only in extracted netlist.
    --set_purge                         Set netlist purge all only in extracted netlist.
    --set_purge_nets                    Set netlist purge nets only in extracted netlist.
"""

from docopt import docopt
import os
import logging

from subprocess import check_call


def main():

    # Switches used in run
    switches = ""

    if args["--run_mode"] in ["flat", "deep", "tiling"]:
        switches = switches + f'-rd run_mode={args["--run_mode"]} '
    else:
        logging.error("Allowed klayout modes are (flat , deep , tiling) only")
        exit()

    if args["--gf180ic"] == "A":
        switches = (
            switches
            + "-rd metal_top=30K -rd mim_option=A -rd metal_level=3LM -rd  poly_res=1K -rd mim_cap=2 "
        )
    elif args["--gf180ic"] == "B":
        switches = (
            switches
            + "-rd metal_top=11K -rd mim_option=B -rd metal_level=4LM -rd  poly_res=1K -rd mim_cap=2 "
        )
    elif args["--gf180ic"] == "C":
        switches = (
            switches
            + "-rd metal_top=9K  -rd mim_option=B -rd metal_level=5LM -rd  poly_res=1K -rd mim_cap=2 "
        )
    else:
        print("gf180ic switch allowed values are (A , B, C) only")
        exit()

    switches = (
        switches + "-rd spice_net_names=false "
        if args["--no_net_names"]
        else switches + "-rd spice_net_names=true "
    )

    switches = (
        switches + "-rd spice_comments=true "
        if args["--set_spice_comments"]
        else switches + "-rd spice_comments=false "
    )

    switches = (
        switches + "-rd scale=true "
        if args["--set_scale"]
        else switches + "-rd scale=false "
    )

    switches = (
        switches + "-rd verbose=true "
        if args["--set_verbose"]
        else switches + "-rd verbose=false "
    )

    switches = (
        switches + "-rd schematic_simplify=true "
        if args["--set_schematic_simplify"]
        else switches + "-rd schematic_simplify=false "
    )

    switches = (
        switches + "-rd net_only=true "
        if args["--set_net_only"]
        else switches + "-rd net_only=false "
    )

    switches = (
        switches + "-rd top_lvl_pins=true "
        if args["--set_top_lvl_pins"]
        else switches + "-rd top_lvl_pins=false "
    )

    switches = (
        switches + "-rd combine=true "
        if args["--set_combine"]
        else switches + "-rd combine=false "
    )

    switches = (
        switches + "-rd purge=true "
        if args["--set_purge"]
        else switches + "-rd purge=false "
    )

    switches = (
        switches + "-rd purge_nets=true "
        if args["--set_purge_nets"]
        else switches + "-rd purge_nets=false "
    )

    switches = (
        switches + f'-rd lvs_sub={args["--lvs_sub"]} '
        if args["--lvs_sub"]
        else switches
    )

    # Generate databases
    if args["--design"]:
        path = args["--design"]
        if args["--design"]:
            file_name = args["--net"].split(".")
        else:
            print(
                "The script must be given a netlist file or a path to be able to run LVS"
            )
            exit()
        check_call(
            f"klayout -b -r {run_lvs_full_path}/gf180ic.lvs -rd input={path} -rd report={file_name[0]}.lyrdb -rd schematic={args['--net']} -rd target_netlist=extracted_netlist_{file_name[0]}.cir -rd thr={workers_count} {switches}",
            shell=True,
        )

    else:
        print("The script must be given a layout file or a path to be able to run LVS")
        exit()


if __name__ == "__main__":

    logging.basicConfig(
        level=logging.DEBUG,
        format="%(asctime)s | %(levelname)-7s | %(message)s",
        datefmt="%d-%b-%Y %H:%M:%S",
    )

    # Args
    args = docopt(__doc__, version="LVS Checker: 0.1")
    workers_count = os.cpu_count() * 2 if args["--thr"] is None else int(args["--thr"])

    run_lvs_full_path = os.path.dirname(os.path.abspath(__file__))

    # ========= Checking Klayout version =========
    klayout_v_ = os.popen("klayout -v").read()
    klayout_v_ = klayout_v_.split("\n")[0]
    klayout_v = int(klayout_v_.split(".")[-1])

    if klayout_v < 8:
        logging.warning(
            "Using this klayout version has not been assesed in this development. Limits are unknown"
        )
        logging.info(f"Your version is: {klayout_v_}")
        logging.info("Prerequisites at a minimum: KLayout 0.27.8")

    # Calling main function
    main()
