#!/usr/bin/env python3
import lxml.etree as ET
import argparse
from sdf_timing import sdfparse
from sdf_timing.utils import get_scale_seconds
from lib.pb_type import get_pb_type_chain
import re
import os
import sys

# Adds output to stderr to track if timing data for a particular BEL was found
# in bels.json
DEBUG = False


def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)


def mergedicts(source, destination):
    """This function recursively merges two dictionaries:
       `source` into `destination"""
    for key, value in source.items():
        if isinstance(value, dict):
            # get node or create one
            node = destination.setdefault(key, {})
            mergedicts(value, node)
        else:
            destination[key] = value

    return destination


def remove_site_number(site):
    """Some sites are numbered in the VPR arch definitions.
       This happens for e.g. SLICE0. This function removes
       trailing numbers from the name"""
    number = re.search(r'\d+$', site)
    if number is not None:
        site = site[:-len(str(number.group()))]
    return site


def gen_all_possibilities(pattern):
    """
    Generates all possible combinations of a pattern if it contains a
    wildcard string in braces eg. "LUT[ABCD]" will yield in "LUTA", "LUTB"
    and so on.

    >>> list(gen_all_possibilities("LUT"))
    ['LUT']

    >>> list(gen_all_possibilities("LUT[ABCD]"))
    ['LUTA', 'LUTB', 'LUTC', 'LUTD']
    """

    # Match the regex
    match = re.match(r"(.*)\[([A-Za-z0-9]+)\](.*)", pattern)

    # Generate combinations
    if match is not None:
        for c in match.group(2):
            yield match.group(1) + c + match.group(3)

    # Not a regex
    else:
        yield pattern


def get_cell_types_and_instances(bel, location, site, bels):
    """This function searches for a bel type and instance
       translation between VPR and Vivado. The translation
       is defined in the `bels` dictionary. If translation
       is found a list of celltypes and bel instances is returned,
       None otherwise"""
    if site not in bels:
        if DEBUG:
            eprint(
                "Site '{}' not found among '{}'".format(
                    site, ", ".join(bels.keys())
                )
            )
        return None
    if bel not in bels[site]:
        if DEBUG:
            eprint(
                "Bel '{}' not found among '{}'".format(
                    bel, ", ".join(bels[site].keys())
                )
            )
        return None
    if location not in bels[site][bel]:
        if DEBUG:
            eprint(
                "Location '{}' not found among '{}'".format(
                    location, ", ".join(bels[site][bel].keys())
                )
            )
        return None

    # Generate a list of tuples (celltype, instance)
    cells = []
    for pattern in bels[site][bel][location]:
        for names in gen_all_possibilities(pattern):
            cells.append(tuple(names.split(".")))

    return cells


def find_timings(timings, bel, location, site, bels, corner, speed_type):
    """This function returns all the timings associated with
       the selected `bel` in `location` and `site`. If timings
       are not found, empty dict is returned"""

    def get_timing(cell, delay, corner, speed_type):
        """
        Gets timing for a particular cornet case. If not fount then chooses
        the next best one.
        """
        entries = cell[delay]['delay_paths'][corner.lower()]
        entry = entries.get(speed_type, None)

        if speed_type == 'min':
            if entry is None:
                entry = entries.get('avg', None)
            if entry is None:
                entry = entries.get('max', None)

        elif speed_type == 'avg':
            if entry is None:
                entry = entries.get('max', None)
            if entry is None:
                entry = entries.get('min', None)

        elif speed_type == 'max':
            if entry is None:
                entry = entries.get('avg', None)
            if entry is None:
                entry = entries.get('min', None)

        if entry is None:
            # if we failed with desired corner, try the opposite
            newcorner = 'FAST' if corner == 'SLOW' else 'SLOW'
            entry = get_timing(cell, delay, newcorner, speed_type)
            assert entry is not None, (delay, corner, speed_type)
        return entry

    # Get cells, reverse the list so former timings will be overwritten by
    # latter ones.
    cells = get_cell_types_and_instances(bel, location, site, bels)
    if cells is None:
        return None

    cells.reverse()

    # Gather CELLs
    cell = dict()
    for ct, inst in cells:
        cell = mergedicts(timings['cells'][ct][inst], cell)

    # Gather timings
    bel_timings = dict()
    for delay in cell:
        if cell[delay]['is_absolute']:
            entry = get_timing(cell, delay, corner.lower(), speed_type)
        elif cell[delay]['is_timing_check']:
            if cell[delay]['type'] == "setuphold":
                # 'setup' and 'hold' are identical
                entry = get_timing(cell, delay, 'setup', speed_type)
            else:
                entry = get_timing(cell, delay, 'nominal', speed_type)
        bel_timings[delay] = float(entry) * get_scale_seconds('1 ns')

    return bel_timings


def get_bel_timings(element, timings, bels, corner, speed_type):
    """This function returns all the timings for an arch.xml
       `element`. It determines the bel location by traversing
       the pb_type chain"""
    pb_chain = get_pb_type_chain(element)
    if len(pb_chain) == 1:
        return None

    if 'max' in element.attrib and element.attrib['max'].startswith(
            '{interconnect'):
        bel = 'ROUTING_BEL'
    else:
        bel = pb_chain[-1]
    location = pb_chain[-2]
    site = remove_site_number(pb_chain[1])

    result = find_timings(
        timings, bel, location, site, bels, corner, speed_type
    )

    if DEBUG:
        print(site, bel, location, result is not None, file=sys.stderr)

    return result


def main():
    parser = argparse.ArgumentParser()

    parser.add_argument(
        '--input_arch', required=True, help="Input arch.xml file"
    )
    parser.add_argument('--sdf_dir', required=True, help="SDF files directory")
    parser.add_argument(
        '--out_arch', required=True, help="Output arch.xml file"
    )
    parser.add_argument(
        '--bels_map',
        required=True,
        help="VPR <-> timing info bels mapping json file"
    )

    args = parser.parse_args()

    arch_xml = ET.ElementTree()
    root_element = arch_xml.parse(args.input_arch)

    # read bels json
    import json
    with open(args.bels_map, 'r') as fp:
        bels = json.load(fp)

    timings = dict()
    files = os.listdir(args.sdf_dir)
    for f in files:
        if not f.endswith('.sdf'):
            continue
        with open(args.sdf_dir + '/' + f, 'r') as fp:
            try:
                tmp = sdfparse.parse(fp.read())
            except Exception as ex:
                print("{}:".format(args.sdf_dir + '/' + f), file=sys.stderr)
                print(repr(ex), file=sys.stderr)
                raise
            mergedicts(tmp, timings)

    if DEBUG:
        with open("/tmp/dump.json", 'w') as fp:
            json.dump(timings, fp, indent=4)

    for dm in root_element.iter('delay_matrix'):
        if dm.attrib['type'] == 'max':
            bel_timings = get_bel_timings(dm, timings, bels, 'SLOW', 'max')
        elif dm.attrib['type'] == 'min':
            bel_timings = get_bel_timings(dm, timings, bels, 'FAST', 'min')
        else:
            assert dm.attrib['type']

        if bel_timings is None:
            continue

        dm.text = dm.text.format(**bel_timings)

    for dc in root_element.iter('delay_constant'):
        format_s = dc.attrib['max']
        max_tim = get_bel_timings(dc, timings, bels, 'SLOW', 'max')
        if max_tim is not None:
            dc.attrib['max'] = format_s.format(**max_tim)

        min_tim = get_bel_timings(dc, timings, bels, 'FAST', 'min')
        if min_tim is not None:
            dc.attrib['min'] = format_s.format(**min_tim)

    for tq in root_element.iter('T_clock_to_Q'):
        format_s = tq.attrib['max']
        max_tim = get_bel_timings(tq, timings, bels, 'SLOW', 'max')
        if max_tim is not None:
            tq.attrib['max'] = format_s.format(**max_tim)

        min_tim = get_bel_timings(tq, timings, bels, 'FAST', 'min')
        if min_tim is not None:
            tq.attrib['min'] = format_s.format(**min_tim)

    for ts in root_element.iter('T_setup'):
        bel_timings = get_bel_timings(ts, timings, bels, 'SLOW', 'max')
        if bel_timings is None:
            continue
        ts.attrib['value'] = ts.attrib['value'].format(**bel_timings)

    for th in root_element.iter('T_hold'):
        bel_timings = get_bel_timings(th, timings, bels, 'FAST', 'min')
        if bel_timings is None:
            continue
        th.attrib['value'] = th.attrib['value'].format(**bel_timings)

    with open(args.out_arch, 'wb') as fp:
        fp.write(ET.tostring(arch_xml))


if __name__ == "__main__":
    main()
