#!/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
import argparse
import sys
import csv

import f4pga.utils.eblif as eblif

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


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


def get_cell_connection(cell, pin):
    """
    Returns the name of the net connected to the given cell pin. Returns None
    if unconnected
    """

    # Only for subckt
    assert cell["type"] == "subckt"

    # Find the connection and return it
    for i in range(1, len(cell["args"])):
        p, net = cell["args"][i].split("=")
        if p == pin:
            return net

    # Not found
    return None


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


def main():
    parser = argparse.ArgumentParser(description="Creates placement constraints other than IOs")

    parser.add_argument(
        "--input", "-i", "-I", type=argparse.FileType("r"), default=sys.stdin, help="The input constraints place file."
    )
    parser.add_argument(
        "--output",
        "-o",
        "-O",
        type=argparse.FileType("w"),
        default=sys.stdout,
        help="The output constraints place file.",
    )
    parser.add_argument("--map", type=argparse.FileType("r"), required=True, help="Clock pinmap CSV file")
    parser.add_argument("--blif", "-b", type=argparse.FileType("r"), required=True, help="BLIF / eBLIF file.")

    args = parser.parse_args()

    # Load clock map
    clock_to_gmux = {}
    for row in csv.DictReader(args.map):
        name = row["name"]
        src_loc = (
            int(row["src.x"]),
            int(row["src.y"]),
            int(row["src.z"]),
        )
        dst_loc = (
            int(row["dst.x"]),
            int(row["dst.y"]),
            int(row["dst.z"]),
        )

        clock_to_gmux[src_loc] = (dst_loc, name)

    # Load EBLIF
    eblif_data = eblif.parse_blif(args.blif)

    # Process the IO constraints file. Pass the constraints unchanged, store
    # them.
    io_constraints = {}

    for line in args.input:

        # Strip, skip comments
        line = line.strip()
        if line.startswith("#"):
            continue

        args.output.write(line + "\n")

        # Get block and its location
        block, x, y, z = line.split()[0:4]
        io_constraints[block] = (
            int(x),
            int(y),
            int(z),
        )

    # Analyze the BLIF netlist. Find clock inputs that go through CLOCK IOB to
    # GMUXes.
    clock_connections = []

    IOB_CELL = {"type": "CLOCK_CELL", "ipin": "I_PAD", "opin": "O_CLK"}
    BUF_CELL = {"type": "GMUX_IP", "ipin": "IP", "opin": "IZ"}

    for inp_net in eblif_data["inputs"]["args"]:

        # This one is not constrained, skip it
        if inp_net not in io_constraints:
            continue

        # Search for a CLOCK cell connected to that net
        for cell in eblif_data["subckt"]:
            if cell["type"] == "subckt" and cell["args"][0] == IOB_CELL["type"]:
                net = get_cell_connection(cell, IOB_CELL["ipin"])
                if net == inp_net:
                    iob_cell = cell
                    break
        else:
            continue

        # Get the output net of the CLOCK cell
        con_net = get_cell_connection(iob_cell, IOB_CELL["opin"])
        if not con_net:
            continue

        # Search for a GMUX connected to the CLOCK cell
        for cell in eblif_data["subckt"]:
            if cell["type"] == "subckt" and cell["args"][0] == BUF_CELL["type"]:
                net = get_cell_connection(cell, BUF_CELL["ipin"])
                if net == con_net:
                    buf_cell = cell
                    break
        else:
            continue

        # Get the output net of the GMUX
        clk_net = get_cell_connection(buf_cell, BUF_CELL["opin"])
        if not clk_net:
            continue

        # Store data
        clock_connections.append((inp_net, iob_cell, con_net, buf_cell, clk_net))

    # Emit constraints for GCLK cells
    for inp_net, iob_cell, con_net, buf_cell, clk_net in clock_connections:

        src_loc = io_constraints[inp_net]
        if src_loc not in clock_to_gmux:
            eprint("ERROR: No GMUX location for input CLOCK pad for net '{}' at {}".format(inp_net, src_loc))
            continue

        dst_loc, name = clock_to_gmux[src_loc]

        # FIXME: Silently assuming here that VPR will name the GMUX block as
        # the GMUX cell in EBLIF. In order to fix that there will be a need
        # to read & parse the packed netlist file.
        line = "{} {} {} {} # {}\n".format(buf_cell["cname"][0], *dst_loc, name)
        args.output.write(line)


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

if __name__ == "__main__":
    main()
