import argparse
import gzip
import logging
import os
import re
import subprocess
from pathlib import Path

try:
    from checks.drc_checks.magic.converters import magic_drc_to_rdb, magic_drc_to_tcl, magic_drc_to_tr_drc, tr2klayout
except ImportError:
    from converters import magic_drc_to_rdb, magic_drc_to_tcl, magic_drc_to_tr_drc, tr2klayout


def check_if_binary_has(word, filename):
    f = gzip.open(filename, 'r', errors='ignore') if 'gz' in str(filename) else open(filename, errors='ignore')
    content = f.read()
    f.close()
    return int(bool(re.search(word, content)))


def is_valid_magic_drc_report(drc_content):
    split_line = '----------------------------------------'
    drc_sections = drc_content.split(split_line)
    return len(drc_sections) >= 2


def violations_count(drc_content):
    """
        design name
        violation message
        list of violations
        Total Count:
    """
    split_line = '----------------------------------------'
    drc_sections = drc_content.split(split_line)
    if len(drc_sections) == 2:
        return 0
    else:
        vio_dict = dict()
        for i in range(1, len(drc_sections) - 1, 2):
            vio_dict[drc_sections[i]] = len(drc_sections[i + 1].split("\n")) - 2
        count = 0
        for key in vio_dict:
            val = vio_dict[key]
            count += val
            logging.error(f"Violation Message \"{str(key.strip())} \"found {str(val)} Times.")
        return count


def magic_gds_drc_check(gds_ut_path, design_name, pdk_root, output_directory):
    parent_directory = Path(__file__).parent
    logs_directory = output_directory / 'logs'
    outputs_directory = output_directory / 'outputs'
    reports_directory = outputs_directory / 'reports'

    design_magic_drc_file_path = reports_directory / f"magic_drc_check.drc.report"

    installed_sram_modules_names = []
    sram_maglef_files_generator = Path(pdk_root / "sky130A" / "libs.ref" / "sky130_sram_macros" / "maglef").glob('*.mag')
    for installed_sram in sram_maglef_files_generator:
        installed_sram_modules_names.append(installed_sram.stem)
    sram_modules_in_gds = []
    for sram in installed_sram_modules_names:
        if check_if_binary_has(sram, gds_ut_path):
            sram_modules_in_gds.append(sram)  # only the name of the module

    magicrc_file_path = parent_directory.parent.parent / 'tech-files' / 'sky130A.magicrc'
    magic_drc_tcl_path = parent_directory / 'magic_drc_check.tcl'
    design_magic_drc_mag_file_path = outputs_directory / f"{design_name}.magic.drc.mag"
    esd_fet = 'sky130_fd_io__signal_5_sym_hv_local_5term'
    # cli arguments for a tcl script has to be a string
    has_sram_as_str = str(check_if_binary_has('sram', gds_ut_path))
    has_esd_fet_as_str = str(check_if_binary_has('sky130_fd_io__signal_5_sym_hv_local_5term', gds_ut_path))
    # TODO(ahmad.nofal@efabless.com): This should be a command line argument
    os.environ['MAGTYPE'] = 'mag'
    run_magic_drc_check_cmd = ['magic', '-noconsole', '-dnull', '-rcfile', magicrc_file_path, magic_drc_tcl_path, gds_ut_path,
                               design_name, pdk_root, design_magic_drc_file_path, design_magic_drc_mag_file_path,
                               ' '.join(sram_modules_in_gds), esd_fet, has_sram_as_str, has_esd_fet_as_str]

    magic_drc_log_file_path = logs_directory / 'magic_drc_check.log'
    with open(magic_drc_log_file_path, 'w') as magic_drc_log:
        process = subprocess.run(run_magic_drc_check_cmd, stderr=magic_drc_log, stdout=magic_drc_log)
    if not design_magic_drc_file_path.exists():
        logging.error(f"No {design_magic_drc_file_path} file produced by the drc check")
        return False

    drc_violations_count = process.returncode
    if drc_violations_count != 0:
        drc_violations_count = (drc_violations_count + 3) / 4  # TODO(ahmad.nofal@efabless.com): Check validity
    magic_drc_total_file_path = logs_directory / 'magic_drc_check.total'
    with open(magic_drc_total_file_path, 'w') as magic_drc_total:
        magic_drc_total.write(str(drc_violations_count))

    # Write all different formats for drc violations reports using converters
    try:
        design_magic_rdb_file_path = reports_directory / f"magic_drc_check.rdb"
        magic_drc_to_rdb.convert(design_magic_drc_file_path, design_magic_rdb_file_path)
        design_magic_drc_tcl_file_path = reports_directory / f"magic_drc_check.tcl"
        magic_drc_to_tcl.convert(design_magic_drc_file_path, design_magic_drc_tcl_file_path)
        design_tr_drc_file_path = reports_directory / f"magic_drc_check.tr"
        magic_drc_to_tr_drc.convert(design_magic_drc_file_path, design_tr_drc_file_path)
        design_klayout_xml_file_path = reports_directory / f"magic_drc_check.xml"
        tr2klayout.convert(design_tr_drc_file_path, design_klayout_xml_file_path, design_name)
    except Exception as e:
        logging.warning(f"Error generating DRC violation report(s), the full set of Magic DRC reports will not be generated. {e}")

    with open(magic_drc_log_file_path) as magic_drc_log:
        log_content = magic_drc_log.read()

    if log_content.find("was used but not defined.") != -1:
        logging.error(f"The GDS is not valid/corrupt contains cells that are used but not defined. Please check: {magic_drc_log_file_path}")
        return False

    if log_content.find("Unrecognized layer (type) name \"<<<<<\"") != -1:
        logging.error(f"The GDS is not valid/corrupt contains cells. Please check: {magic_drc_log_file_path}")
        return False

    with open(design_magic_drc_file_path) as magic_drc_report:
        drc_content = magic_drc_report.read()

    if not is_valid_magic_drc_report(drc_content):
        logging.error(f"Incomplete DRC Report. Maybe you ran out of RAM. Please check: {magic_drc_log_file_path}")
        return False
    else:
        count = violations_count(drc_content)
        logging.info(f"{count} DRC violations") if count == 0 else logging.error(f"{count} DRC violations")
        return True if count == 0 else False


if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG, format=f"%(asctime)s | %(levelname)-7s | %(message)s", datefmt='%d-%b-%Y %H:%M:%S')
    parser = argparse.ArgumentParser(description='Runs magic and klayout drc checks on a given GDS.')
    parser.add_argument('--gds_input_file_path', '-g', required=True, help='GDS File to apply DRC checks on')
    parser.add_argument('--output_directory', '-o', required=True, help='Output Directory')
    parser.add_argument('--pdk_root', '-p', required=True, help='PDK Path')
    parser.add_argument('--design_name', '-d', required=True, help='Design Name')

    args = parser.parse_args()
    gds_input_file_path = Path(args.gds_input_file_path)
    output_directory = Path(args.output_directory)
    pdk_root = Path(args.pdk_root)
    design_name = args.design_name

    if gds_input_file_path.exists() and gds_input_file_path.suffix == ".gds":
        if output_directory.exists() and output_directory.is_dir():
            if magic_gds_drc_check(gds_input_file_path, args.design_name, pdk_root, output_directory):
                logging.info("Magic GDS DRC Clean")
            else:
                logging.info("Magic GDS DRC Dirty")
        else:
            logging.error(f"{output_directory} is not valid")
    else:
        logging.error(f"{gds_input_file_path} is not valid")
