#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2022 F4PGA 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.
#
# SPDX-License-Identifier: Apache-2.0
""" Convert a PCF file into a VPR io.place file. """
import argparse
import csv
import sys
import re
from collections import defaultdict

import f4pga.utils.vpr_io_place as vpr_io_place
from f4pga.utils.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()
