""" Convert a PCF file into a VPR io.place file. """
import argparse
import csv
import sys
import re
from collections import defaultdict

import vpr_io_place
from lib.parse_pcf import parse_simple_pcf

# =============================================================================

# Known IOB types and VPR cells that can be placed at their sites
IOB_TYPES = {
    "CLOCK": ["PB-CLOCK", ],
    "BIDIR": ["PB-BIDIR", ],
    "SDIOMUX": ["PB-SDIOMUX", ],
}

BLOCK_INSTANCE_RE = re.compile(r"^(?P<name>\S+)\[(?P<index>[0-9]+)\]$")

# =============================================================================


def main():
    parser = argparse.ArgumentParser(
        description='Convert a PCF file into a VPR io.place file.'
    )
    parser.add_argument(
        "--pcf",
        "-p",
        "-P",
        type=argparse.FileType('r'),
        required=True,
        help='PCF input file'
    )
    parser.add_argument(
        "--blif",
        "-b",
        type=argparse.FileType('r'),
        required=True,
        help='BLIF / eBLIF file'
    )
    parser.add_argument(
        "--map",
        "-m",
        "-M",
        type=argparse.FileType('r'),
        required=True,
        help='Pin map CSV file'
    )
    parser.add_argument(
        "--output",
        "-o",
        "-O",
        type=argparse.FileType('w'),
        default=sys.stdout,
        help='The output io.place file'
    )
    parser.add_argument(
        "--net",
        "-n",
        type=argparse.FileType('r'),
        required=True,
        help='top.net file'
    )

    args = parser.parse_args()

    io_place = vpr_io_place.IoPlace()
    io_place.read_io_list_from_eblif(args.blif)
    io_place.load_block_names_from_net_file(args.net)

    # Map of pad names to VPR locations.
    pad_map = defaultdict(lambda: dict())
    pad_alias_map = defaultdict(lambda: dict())

    for pin_map_entry in csv.DictReader(args.map):

        if pin_map_entry['type'] not in IOB_TYPES:
            continue

        name = pin_map_entry['name']
        alias = ""
        if 'alias' in pin_map_entry:
            alias = pin_map_entry['alias']

        for t in IOB_TYPES[pin_map_entry['type']]:
            pad_map[name][t] = (
                int(pin_map_entry['x']),
                int(pin_map_entry['y']),
                int(pin_map_entry['z']),
            )
            if 'alias' in pin_map_entry:
                pad_alias_map[alias] = name

    used_pads = set()

    for pcf_constraint in parse_simple_pcf(args.pcf):

        # Skip non-io constraints
        if type(pcf_constraint).__name__ != 'PcfIoConstraint':
            continue

        pad_name = pcf_constraint.pad
        if not io_place.is_net(pcf_constraint.net):
            print(
                'PCF constraint "{}" from line {} constraints net {} \
                        which is not in available netlist:\n{}'.format(
                    pcf_constraint.line_str, pcf_constraint.line_num,
                    pcf_constraint.net, '\n'.join(io_place.get_nets())
                ),
                file=sys.stderr
            )
            sys.exit(1)

        if pad_name not in pad_map and pad_name not in pad_alias_map:
            print(
                'PCF constraint "{}" from line {} constraints pad {} \
                        which is not in available pad map:\n{}'.format(
                    pcf_constraint.line_str, pcf_constraint.line_num, pad_name,
                    '\n'.join(sorted(pad_map.keys()))
                ),
                file=sys.stderr
            )
            sys.exit(1)

        # Alias is specified in pcf file so assign it to corresponding pad name
        if pad_name in pad_alias_map:
            pad_name = pad_alias_map[pad_name]

        # Catch the same pad used multiple times
        if pad_name in used_pads:
            print(
                'PCF constraint "{}" from line {} constraints pad {} \
                        which has already been constrained'.format(
                    pcf_constraint.line_str, pcf_constraint.line_num, pad_name
                ),
                file=sys.stderr
            )
            sys.exit(1)
        used_pads.add(pad_name)

        # Get the top-level block instance, strip its index
        inst = io_place.get_top_level_block_instance_for_net(
            pcf_constraint.net
        )
        if inst is None:
            continue

        match = BLOCK_INSTANCE_RE.match(inst)
        assert match is not None, inst

        inst = match.group("name")

        # Pick correct loc for that pb_type
        locs = pad_map[pad_name]
        if inst not in locs:
            print(
                'PCF constraint "{}" from line {} constraints net {} of a block type {} \
                        to a location for block types:\n{}'.format(
                    pcf_constraint.line_str, pcf_constraint.line_num,
                    pcf_constraint.net, inst,
                    '\n'.join(sorted(list(locs.keys())))
                ),
                file=sys.stderr
            )
            sys.exit(1)

        # Constraint the net (block)
        loc = locs[inst]
        io_place.constrain_net(
            net_name=pcf_constraint.net,
            loc=loc,
            comment=pcf_constraint.line_str
        )

    io_place.output_io_place(args.output)


# =============================================================================

if __name__ == '__main__':
    main()
