#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019-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.
"""


from argparse import ArgumentParser, FileType
from pathlib import Path
from csv import DictReader as csv_DictReader
from sys import stdout, stderr, exit as sys_exit
from json import dump as json_dump, load as json_load

from f4pga.utils.vpr_io_place import IoPlace
from f4pga.utils.pcf import parse_simple_pcf


def p_main(blif, map, net, pcf=None, output=stdout, iostandard_defs_file=None, iostandard="LVCMOS33", drive=12):
    io_place = IoPlace()
    io_place.read_io_list_from_eblif(blif)
    io_place.load_block_names_from_net_file(net)

    # Map of pad names to VPR locations.
    pad_map = {}

    for pin_map_entry in csv_DictReader(map):
        pad_map[pin_map_entry["name"]] = (
            (
                int(pin_map_entry["x"]),
                int(pin_map_entry["y"]),
                int(pin_map_entry["z"]),
            ),
            pin_map_entry["is_output"],
            pin_map_entry["iob"],
            pin_map_entry["real_io_assoc"],
        )

    iostandard_defs = {}

    # Load iostandard constraints. This is a temporary workaround that allows
    # to pass them into fasm2bels. As soon as there is support for XDC this
    # will not be needed anymore.
    # If there is a JSON file with the same name as the PCF file then it is
    # loaded and used as iostandard constraint source NOT for the design but
    # to be used in fasm2bels.
    iostandard_constraints = {}

    if pcf is not None:
        fname = Path(pcf.name.replace(".pcf", ".json"))
        if fname.is_file():
            with fname.open("r") as fp:
                iostandard_constraints = json_load(fp)
    net_to_pad = io_place.net_to_pad
    if pcf is not None:
        net_to_pad |= set((constr.net, constr.pad) for constr in parse_simple_pcf(pcf))
    # Check for conflicting pad constraints
    net_to_pad_map = dict()
    for net, pad in net_to_pad:
        if net not in net_to_pad_map:
            net_to_pad_map[net] = pad
        elif pad != net_to_pad_map[net]:
            print(
                f"ERROR: Conflicting pad constraints for net {net}:\n{pad}\n{net_to_pad_map[net]}",
                file=stderr,
            )
            sys_exit(1)

    # Constrain nets
    for net, pad in net_to_pad:
        if not io_place.is_net(net):
            nets = "\n".join(io_place.get_nets())
            print(
                f"ERROR: Constrained net {net} is not in available netlist:\n{nets}",
                file=stderr,
            )
            sys_exit(1)

        if pad not in pad_map:
            pads = "\n".join(sorted(pad_map.keys()))
            print(
                f"ERROR: Constrained pad {pad} is not in available pad map:\n{pads}",
                file=stderr,
            )
            sys_exit(1)

        loc, is_output, iob, real_io_assoc = pad_map[pad]

        io_place.constrain_net(net_name=net, loc=loc, comment="set_property LOC {} [get_ports {{{}}}]".format(pad, net))
        if real_io_assoc == "True":
            iostandard_defs[iob] = (
                iostandard_constraints[pad]
                if pad in iostandard_constraints
                else ({"DRIVE": drive, "IOSTANDARD": iostandard} if is_output else {"IOSTANDARD": iostandard})
            )

    io_place.output_io_place(output)

    # Write iostandard definitions
    if iostandard_defs_file is not None:
        with Path(iostandard_defs_file).open("w") as f:
            json_dump(iostandard_defs, f, indent=2)


def main(
    blif,
    map,
    net,
    pcf=None,
    output=None,
    iostandard_defs_file=None,
    iostandard="LVCMOS33",
    drive=12,
):
    p_main(
        blif=Path(blif).open("r"),
        map=Path(map).open("r"),
        net=Path(net).open("r"),
        pcf=None if pcf is None else pcf,
        output=stdout if output is None else Path(output).open("w"),
        iostandard_defs_file=iostandard_defs_file,
        iostandard=iostandard,
        drive=drive,
    )


if __name__ == "__main__":
    parser = ArgumentParser(description="Convert a PCF file into a VPR io.place file.")
    parser.add_argument("--pcf", "-p", "-P", type=FileType("r"), required=False, help="PCF input file")
    parser.add_argument("--blif", "-b", type=FileType("r"), required=True, help="BLIF / eBLIF file")
    parser.add_argument("--map", "-m", "-M", type=FileType("r"), required=True, help="Pin map CSV file")
    parser.add_argument("--output", "-o", "-O", type=FileType("w"), default=stdout, help="The output io.place file")
    parser.add_argument("--iostandard_defs", help="(optional) Output IOSTANDARD def file")
    parser.add_argument(
        "--iostandard",
        default="LVCMOS33",
        help="Default IOSTANDARD to use for pins",
    )
    parser.add_argument(
        "--drive",
        type=int,
        default=12,
        help="Default drive to use for pins",
    )
    parser.add_argument("--net", "-n", type=FileType("r"), required=True, help="top.net file")

    args = parser.parse_args()

    p_main(
        blif=args.blif,
        map=args.map,
        net=args.net,
        pcf=args.pcf,
        output=args.output,
        iostandard_defs_file=args.iostandard_defs,
        iostandard=args.iostandard,
        drive=args.drive,
    )
