#!/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.quicklogic.pinmap_parse import read_pinmapfile_data
from f4pga.utils.quicklogic.pinmap_parse import vec_to_scalar

from f4pga.utils.pcf import parse_simple_pcf

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

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


# =============================================================================
def gen_io_def(args):
    """
    Generate io.place file from pcf file
    """
    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)

    # Load all the necessary data from the pinmap_xml
    io_cells, port_map = read_pinmapfile_data(args.pinmap_xml)

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

    with open(args.csv_file, mode="r") as csv_fp:
        reader = csv.DictReader(csv_fp)
        for line in reader:
            port_name_list = vec_to_scalar(line["port_name"])
            pin_name = vec_to_scalar(line["mapped_pin"])
            gpio_type = line["GPIO_type"]

            if len(port_name_list) != len(pin_name):
                print(
                    'CSV port name "{}" length does not match with mapped pin name "{}" length'.format(
                        line["port_name"], line["mapped_pin"]
                    ),
                    file=sys.stderr,
                )
                sys.exit(1)

            for port, pin in zip(port_name_list, pin_name):
                if port in port_map:
                    curr_map = port_map[port]
                    if gpio_type is None or gpio_type == "":
                        pad_map[pin] = (int(curr_map.x), int(curr_map.y), int(curr_map.z))
                    else:
                        gpio_pin = pin + ":" + gpio_type.strip()
                        pad_map[gpio_pin] = (int(curr_map.x), int(curr_map.y), int(curr_map.z))
                else:
                    print(
                        'Port name "{}" specified in csv file "{}" is invalid. {} "{}"'.format(
                            line["port_name"], args.csv_file, "Specify from port names in xml file", args.pinmap_xml
                        ),
                        file=sys.stderr,
                    )
                    sys.exit(1)

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

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

            # 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")

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

    if io_place.constraints:
        io_place.output_io_place(args.output)


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


def main():
    """
    Convert a PCF file into a VPR io.place file
    """
    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(
        "--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")

    parser.add_argument("--pinmap_xml", type=str, required=True, help="Input pin-mapping xml file")
    parser.add_argument("--csv_file", type=str, required=True, help="Input user-defined pinmap CSV file")

    args = parser.parse_args()

    gen_io_def(args)


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

if __name__ == "__main__":
    main()
