#!/usr/bin/env python3
import argparse
import pickle
import itertools
import os
from collections import defaultdict

from sdf_timing import sdfparse
from sdf_timing.utils import get_scale_seconds

from data_structs import Pin, PinDirection, Cell, CellType, ClockCell, Loc, LocMap, \
    Tile, TileType, Connection, ConnectionLoc, ConnectionType, PackagePin, VprSwitch, \
    VprSegment, Quadrant
from utils import get_loc_of_cell, find_cell_in_tile
from utils import get_pin_name

from timing import compute_switchbox_timing_model
from timing import populate_switchbox_timing, copy_switchbox_timing
from timing import add_vpr_switches_for_cell

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

# Grid margin size (left, top, right, bottom)
GRID_MARGIN = (3, 2, 2, 2)

# IO cell types to ignore. They do not correspond to routable IO pads.
IGNORED_IO_CELL_TYPES = (
    "VCC",
    "GND",
)

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

DEBUG = False


def is_loc_within_limit(loc, limit):
    """
    Returns true when the given location lies within the given limit.
    Returns true if the limit is None. Coordinates in the limit are
    inclusive.
    """

    if limit is None:
        return True

    if loc.x < limit[0] or loc.x > limit[2]:
        return False
    if loc.y < limit[1] or loc.y > limit[3]:
        return False

    return True


def is_loc_free(loc, tile_grid):
    """
    Checks whether a location in the given tilegrid is free.
    """

    if loc not in tile_grid:
        return True
    if tile_grid[loc] is None:
        return True

    return False


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


def process_cells_library(cells_library):
    """
    Processes the cells library, modifies some of them according to
    requirements of their VPR representation
    """
    vpr_cells_library = {}

    for cell_type, cell in cells_library.items():

        # If the cell is a QMUX add the missing QCLKIN1 and QCLKIN2
        # input pins.
        if cell_type == "QMUX":
            cell_pins = cell.pins

            for i in [1, 2]:
                cell_pins.append(
                    Pin(
                        name="QCLKIN{}".format(i),
                        direction=PinDirection.INPUT,
                        attrib={"hardWired": "true"}
                    )
                )

            # Substitute the cell
            vpr_cells_library[cell_type] = CellType(
                type=cell_type, pins=cell_pins
            )

        # Copy the cell
        vpr_cells_library[cell_type] = cell

    return vpr_cells_library


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


def fixup_cand_loc(vpr_loc, phy_loc):
    """
    Fixes up location of a CAND cell so that all of them occupy the same row.
    Returns the cell location in VPR coordinates
    """

    # Even, don't modify
    if not (phy_loc.y % 2):
        return vpr_loc

    # Odd, shift down by 1
    return Loc(vpr_loc.x, vpr_loc.y + 1, vpr_loc.z)


def add_synthetic_cell_and_tile_types(tile_types, cells_library):

    # Add a synthetic tile types for the VCC and GND const sources.
    # Models of the VCC and GND cells are already there in the cells_library.
    for const in ["VCC", "GND"]:
        tile_type = TileType("SYN_{}".format(const), {const: 1})
        tile_type.make_pins(cells_library)
        tile_types[tile_type.type] = tile_type


def make_tile_type(cells, cells_library, tile_types, fake_const_pin=False):
    """
    Creates a tile type given a list of cells that constitute to it.
    """

    # Count cell types
    cell_types = sorted([c.type for c in cells])
    cell_counts = {t: 0 for t in cell_types}

    for cell in cells:
        cell_counts[cell.type] += 1

    # Format type name
    parts = []
    for t, c in cell_counts.items():
        if c == 1:
            parts.append(t)
        else:
            parts.append("{}x{}".format(c, t))

    type_name = "_".join(parts).upper()

    # If the new tile type already exists, use the existing one
    if type_name in tile_types:
        return tile_types[type_name]

    # Create the new tile type
    tile_type = TileType(
        type=type_name, cells=cell_counts, fake_const_pin=fake_const_pin
    )

    # Create pins
    tile_type.make_pins(cells_library)

    # Add it to the list
    tile_types[type_name] = tile_type
    return tile_type


def strip_cells(tile, cell_types, tile_types, cells_library):
    """
    Removes cells of the particular type from the tile and tile_type.
    Possibly creates a new tile type
    """
    tile_type = tile_types[tile.type]

    # Check if there is something to remove
    if not len(set(cell_types) & set(tile_type.cells.keys())):
        return tile

    # Filter cells
    new_cells = [c for c in tile.cells if c.type not in cell_types]
    if not new_cells:
        return None

    # Create the new tile type and tile
    new_tile_type = make_tile_type(
        new_cells, cells_library, tile_types, tile_type.fake_const_pin
    )
    new_tile = Tile(type=new_tile_type.type, name=tile.name, cells=new_cells)

    return new_tile


def process_tilegrid(
        tile_types,
        tile_grid,
        clock_cells,
        cells_library,
        grid_size,
        grid_offset,
        grid_limit=None
):
    """
    Processes the tilegrid. May add/remove tiles. Returns a new one.
    """

    vpr_tile_grid = {}
    fwd_loc_map = {}
    bwd_loc_map = {}
    ram_blocks = []
    mult_blocks = []
    vpr_clock_cells = {}

    def add_loc_map(phy_loc, vpr_loc):
        fwd_loc_map[phy_loc] = vpr_loc
        bwd_loc_map[vpr_loc] = phy_loc

    # Add a fake constant connector pin to LOGIC tile type
    tile_type = tile_types["LOGIC"]
    tile_type.fake_const_pin = True
    tile_type.make_pins(cells_library)

    # Generate the VPR tile grid
    for phy_loc, tile in tile_grid.items():

        # Limit the grid range
        if not is_loc_within_limit(phy_loc, grid_limit):
            continue

        vpr_loc = Loc(
            x=phy_loc.x + grid_offset[0], y=phy_loc.y + grid_offset[1], z=0
        )

        # If the tile contains QMUX or CAND then strip it. Possibly create a
        # new tile type.
        tile_type = tile_types[tile.type]
        if "QMUX" in tile_type.cells or "CAND" in tile_type.cells:

            # Store the stripped cells
            for cell in tile.cells:
                if cell.type in ["QMUX", "CAND"]:

                    # Find it in the physical clock cell list
                    if cell.name not in clock_cells:
                        print(
                            "WARNING: Clock cell '{}' not on the clock cell list!"
                            .format(cell.name)
                        )
                        continue

                    # Relocate CAND cells so that they occupy only even rows
                    if cell.type == "CAND":
                        cell_loc = fixup_cand_loc(vpr_loc, phy_loc)
                    else:
                        cell_loc = vpr_loc

                    # Get the orignal cell
                    clock_cell = clock_cells[cell.name]
                    pin_map = clock_cell.pin_map

                    # If the cell is QMUX then extend its pin map with
                    # QCLKIN0 and QCLKIN1 pins that are not present in the
                    # techfile.
                    if clock_cell.type == "QMUX":
                        gmux_base = int(pin_map["QCLKIN0"].rsplit("_")[1])
                        for i in [1, 2]:
                            key = "QCLKIN{}".format(i)
                            val = "GMUX_{}".format((gmux_base + i) % 5)
                            pin_map[key] = val

                    # Add the cell
                    clock_cell = ClockCell(
                        type=clock_cell.type,
                        name=clock_cell.name,
                        loc=cell_loc,
                        quadrant=clock_cell.quadrant,
                        pin_map=pin_map
                    )

                    vpr_clock_cells[clock_cell.name] = clock_cell

            # Strip the cells
            tile = strip_cells(
                tile, ["QMUX", "CAND"], tile_types, cells_library
            )
            if tile is None:
                continue

        # The tile contains a BIDIR or CLOCK cell. it is an IO tile
        tile_type = tile_types[tile.type]
        if "BIDIR" in tile_type.cells or "CLOCK" in tile_type.cells:

            # For the BIDIR cell create a synthetic tile
            if "BIDIR" in tile_type.cells:
                assert tile_type.cells["BIDIR"] == 1

                cells = [c for c in tile.cells if c.type == "BIDIR"]
                new_type = make_tile_type(cells, cells_library, tile_types)

                add_loc_map(phy_loc, vpr_loc)
                vpr_tile_grid[vpr_loc] = Tile(
                    type=new_type.type, name=tile.name, cells=cells
                )

            # For the CLOCK cell create a synthetic tile
            if "CLOCK" in tile_type.cells:
                assert tile_type.cells["CLOCK"] == 1

                cells = [c for c in tile.cells if c.type == "CLOCK"]
                new_type = make_tile_type(cells, cells_library, tile_types)

                # If the tile has a BIDIR cell then place the CLOCK tile in a
                # free location next to the original one.
                if "BIDIR" in tile_type.cells:
                    for ox, oy in ((-1, 0), (+1, 0), (0, -1), (0, +1)):
                        test_loc = Loc(x=phy_loc.x + ox, y=phy_loc.y + oy, z=0)
                        if is_loc_free(test_loc, tile_grid):
                            new_loc = Loc(
                                x=vpr_loc.x + ox,
                                y=vpr_loc.y + oy,
                                z=vpr_loc.z
                            )
                            break
                    else:
                        assert False, (
                            "No free location to place CLOCK tile", vpr_loc
                        )

                # Don't move
                else:
                    new_loc = vpr_loc

                # Add only the backward location correspondence for CLOCK tile
                bwd_loc_map[new_loc] = phy_loc
                vpr_tile_grid[new_loc] = Tile(
                    type=new_type.type, name=tile.name, cells=cells
                )

# Mults and RAMs occupy multiple cells
# We'll create a synthetic tile with a single cell for each
# RAM and MULT block
        if "RAM" in tile_type.cells or "MULT" in tile_type.cells:
            for cell in tile.cells:
                # Check if the current location is not taken
                # this could happen because RAM and MULTS share
                # the same location. General rule here is that
                # we create a synthetic Tile/Cell in the first
                # available neighboring location of the original block of cells
                if cell.type == 'RAM':
                    cells_set = ram_blocks
                elif cell.type == 'MULT':
                    cells_set = mult_blocks
                else:
                    continue

                # Find free location in the physical tile grid close to the
                # original one. Once found, convert it to location in the
                # VPR tile grid.
                for ox, oy in ((0, 0), (0, -1), (0, +1), (-1, 0), (+1, 0)):
                    test_loc = Loc(x=phy_loc.x + ox, y=phy_loc.y + oy, z=0)
                    if is_loc_free(test_loc, tile_grid):
                        new_loc = Loc(
                            x=vpr_loc.x + ox, y=vpr_loc.y + oy, z=vpr_loc.z
                        )
                        break
                else:
                    assert False, "No free location to place {} tile".format(
                        cell.type
                    )

                # The VPR location is already occupied. Probably another
                # instance of the same cell is already there.
                if not is_loc_free(new_loc, vpr_tile_grid):
                    continue

                bwd_loc_map[new_loc] = phy_loc
                if cell.name not in cells_set:
                    cells_set.append(cell.name)
                    tile_type = make_tile_type(
                        [cell], cells_library, tile_types
                    )
                    vpr_tile_grid[new_loc] = Tile(
                        tile_type.type, name=cell.type, cells=[cell]
                    )

        # The tile contains SDIOMUX cell(s). This is an IO tile.
        if "SDIOMUX" in tile_type.cells:

            # Split the tile into individual SDIOMUX cells. Each one will be
            # inside a synthetic tile occupying different grid location.
            cells = [c for c in tile.cells if c.type == "SDIOMUX"]
            for i, cell in enumerate(cells):

                # Create a synthetic tile that will hold just the SDIOMUX cell
                new_type = make_tile_type([cell], cells_library, tile_types)

                # Choose a new location for the tile
                # FIXME: It is assumed that SDIOMUX tiles are on the left edge
                # of the grid and there is enough space to split them.
                new_loc = Loc(vpr_loc.x - i, vpr_loc.y, vpr_loc.z)
                assert new_loc.x >= 1, new_loc

                # For the offset 0 add the full mapping, for others, just the
                # backward correspondence.
                if new_loc == vpr_loc:
                    add_loc_map(phy_loc, new_loc)
                else:
                    bwd_loc_map[new_loc] = phy_loc

                # Change index of the cell
                new_cell = Cell(
                    type=cell.type, index=0, name=cell.name, alias=cell.alias
                )

                # Add the tile instance
                vpr_tile_grid[new_loc] = Tile(
                    type=new_type.type, name=tile.name, cells=[new_cell]
                )

        # A homogeneous tile
        if len(tile_type.cells) == 1:
            cell_type = list(tile_type.cells.keys())[0]

            # LOGIC, keep as is
            if cell_type == "LOGIC":
                add_loc_map(phy_loc, vpr_loc)
                vpr_tile_grid[vpr_loc] = tile
                continue

            # GMUX, split individual GMUX cells into sub-tiles
            elif cell_type == "GMUX":

                for i, cell in enumerate(tile.cells):

                    # Create a tile type for a single GMUX cell
                    new_type = make_tile_type(
                        [cell], cells_library, tile_types
                    )
                    # New location
                    new_loc = Loc(vpr_loc.x, vpr_loc.y, cell.index)

                    # For the offset 0 add the full mapping, for others, just the
                    # backward correspondence.
                    if new_loc == vpr_loc:
                        add_loc_map(phy_loc, new_loc)
                    else:
                        bwd_loc_map[new_loc] = phy_loc

                    # Change index of the cell
                    new_cell = Cell(
                        type=cell.type,
                        index=0,
                        name=cell.name,
                        alias=cell.alias
                    )

                    # Add the tile instance
                    vpr_tile_grid[new_loc] = Tile(
                        type=new_type.type, name=tile.name, cells=[new_cell]
                    )

                continue

    # Find the ASSP tile. There are multiple tiles that contain the ASSP cell
    # but in fact there is only one ASSP cell for the whole FPGA which is
    # "distributed" along top and left edge of the grid.
    if "ASSP" in tile_types:

        # Verify that the location is empty
        assp_loc = Loc(x=1, y=1, z=0)
        assert is_loc_free(vpr_tile_grid, assp_loc), ("ASSP", assp_loc)

        # Place the ASSP tile
        vpr_tile_grid[assp_loc] = Tile(
            type="ASSP",
            name="ASSP",
            cells=[Cell(type="ASSP", index=0, name="ASSP", alias=None)]
        )

        # Remove "FBIO_*" pins from the ASSP tile. These pins are handled by
        # SDIOMUX IO cells
        tile_type = tile_types["ASSP"]
        tile_type.pins = [p for p in tile_type.pins if "FBIO_" not in p.name]

    # Insert synthetic VCC and GND source tiles.
    # FIXME: This assumes that the locations specified are empty!
    for const, loc in [("VCC", Loc(x=2, y=1, z=0)), ("GND", Loc(x=3, y=1,
                                                                z=0))]:

        # Verify that the location is empty
        assert is_loc_free(vpr_tile_grid, loc), (const, loc)

        # Add the tile instance
        name = "SYN_{}".format(const)
        vpr_tile_grid[loc] = Tile(
            type=name,
            name=name,
            cells=[Cell(type=const, index=0, name=const, alias=None)]
        )

    # Extend the grid by 1 on the right and bottom side. Fill missing locs
    # with empty tiles.
    for x, y in itertools.product(range(grid_size[0]), range(grid_size[1])):
        loc = Loc(x=x, y=y, z=0)

        if loc not in vpr_tile_grid:
            vpr_tile_grid[loc] = None

    return vpr_tile_grid, vpr_clock_cells, LocMap(
        fwd=fwd_loc_map, bwd=bwd_loc_map
    ),


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


def process_switchbox_grid(
        phy_switchbox_grid, loc_map, grid_offset, grid_limit=None
):
    """
    Processes the switchbox grid
    """

    fwd_loc_map = loc_map.fwd
    bwd_loc_map = loc_map.bwd

    def add_loc_map(phy_loc, vpr_loc):

        if phy_loc in fwd_loc_map:
            assert fwd_loc_map[phy_loc] == vpr_loc, (phy_loc, vpr_loc)
        else:
            fwd_loc_map[phy_loc] = vpr_loc

        if vpr_loc in bwd_loc_map:
            assert bwd_loc_map[vpr_loc] == phy_loc, (phy_loc, vpr_loc)
        else:
            bwd_loc_map[vpr_loc] = phy_loc

    # Remap locations
    vpr_switchbox_grid = {}
    for phy_loc, switchbox_type in phy_switchbox_grid.items():

        # Limit the grid range
        if not is_loc_within_limit(phy_loc, grid_limit):
            continue

        # compute VPR grid location
        vpr_loc = Loc(
            x=phy_loc.x + grid_offset[0], y=phy_loc.y + grid_offset[1], z=0
        )

        # Place the switchbox
        vpr_switchbox_grid[vpr_loc] = switchbox_type

        # Add location correspondence
        add_loc_map(phy_loc, vpr_loc)

    return vpr_switchbox_grid, LocMap(fwd=fwd_loc_map, bwd=bwd_loc_map),


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


def process_connections(
        phy_connections, loc_map, vpr_tile_grid, phy_tile_grid, grid_limit=None
):
    """
    Process the connection list.
    """

    # Remap locations, create the VPR connection list
    vpr_connections = []
    for connection in phy_connections:

        # Reject connections that reach outsite the grid limit
        if not is_loc_within_limit(connection.src.loc, grid_limit):
            continue
        if not is_loc_within_limit(connection.dst.loc, grid_limit):
            continue

        # Remap source and destination coordinates
        eps = [connection.src, connection.dst]
        for j, ep in enumerate(eps):
            phy_loc = ep.loc
            vpr_loc = loc_map.fwd[phy_loc]

            vpr_pin = ep.pin

            # If the connection mentions a CAND cell, fixup its location
            if "CAND" in ep.pin and ep.type == ConnectionType.CLOCK:
                vpr_loc = fixup_cand_loc(vpr_loc, phy_loc)

            # If the connection mentions a GMUX cell, remap its Z location so
            # it points to the correct sub-tile
            if "GMUX" in ep.pin and ep.type == ConnectionType.TILE:

                # Modify the cell name, use always "GMUX0"
                cell, pin = ep.pin.split("_", maxsplit=1)
                vpr_pin = "GMUX0_{}".format(pin)

                # Modify the location according to the cell index
                z = int(cell[-1])  # FIXME: Assuming indices 0-9
                vpr_loc = Loc(vpr_loc.x, vpr_loc.y, z)

            # Update the endpoint
            eps[j] = ConnectionLoc(loc=vpr_loc, pin=vpr_pin, type=ep.type)

        # Add the connection
        vpr_connections.append(
            Connection(src=eps[0], dst=eps[1], is_direct=connection.is_direct)
        )

    # Remap locations of connections that go to CLOCK pads. A physical
    # BIDIR+CLOCK tile is split into separate BIDIR and CLOCK tiles.
    for i, connection in enumerate(vpr_connections):

        eps = [connection.src, connection.dst]
        for j, ep in enumerate(eps):

            # This endpoint is not relevant to a CLOCK cell
            if not ep.pin.startswith("CLOCK"):
                continue

            # The endpoint location points to a BIDIR tile. Find the assocated
            # CLOCK tile
            org_loc = loc_map.bwd[ep.loc]
            for vpr_loc, phy_loc in loc_map.bwd.items():
                if phy_loc == org_loc and vpr_loc != ep.loc:
                    clock_loc = vpr_loc
                    break
            else:
                assert False, (
                    "Couldn't find a CLOCK cell in the VPR grid!", connection
                )

            eps[j] = ConnectionLoc(
                loc=clock_loc,
                pin=ep.pin,
                type=ep.type,
            )

        # Modify the connection
        vpr_connections[i] = Connection(
            src=eps[0], dst=eps[1], is_direct=connection.is_direct
        )

    # Find SFBIO connections, map their endpoints to SDIOMUX tiles
    # FIXME: This should be read from the techfine. Definition of the SDIOMUX
    # cell has  "realPortName" fields.
    SDIOMUX_PIN_MAP = {
        "FBIO_In": "IZ",
        "FBIO_In_En": "IE",
        "FBIO_Out": "OQI",
        "FBIO_Out_En": "OE",
    }

    for i, connection in enumerate(vpr_connections):

        eps = [connection.src, connection.dst]
        for j, ep in enumerate(eps):

            # Must have "ASSP" and "FBIO_" in name and refer to a tile.
            if "ASSP" not in ep.pin:
                continue
            if "FBIO_" not in ep.pin:
                continue
            if ep.type != ConnectionType.TILE:
                continue

            # Get the pin name and index
            pin_name, pin_index = get_pin_name(ep.pin)
            assert pin_index is not None, ep

            # Strip cell name
            pin_name = pin_name.split("_", maxsplit=1)[1]

            # Find where is an SDIOMUX cell for that index
            cell_name = "SFB_{}_IO".format(pin_index)

            # New location and pin name
            new_loc = get_loc_of_cell(cell_name, vpr_tile_grid)
            cell = find_cell_in_tile(cell_name, vpr_tile_grid[new_loc])

            new_pin = "{}{}_{}".format(
                cell.type, cell.index, SDIOMUX_PIN_MAP[pin_name]
            )

            eps[j] = ConnectionLoc(
                loc=new_loc,
                pin=new_pin,
                type=ep.type,
            )

        # Modify the connection
        vpr_connections[i] = Connection(
            src=eps[0], dst=eps[1], is_direct=connection.is_direct
        )

    # Find locations of "special" tiles
    special_tile_loc = {"ASSP": None}

    for loc, tile in vpr_tile_grid.items():
        if tile is not None and tile.type in special_tile_loc:
            assert special_tile_loc[tile.type] is None, tile
            special_tile_loc[tile.type] = loc

    # Map connections going to/from them to their locations in the VPR grid
    for i, connection in enumerate(vpr_connections):

        # Process connection endpoints
        eps = [connection.src, connection.dst]
        for j, ep in enumerate(eps):

            if ep.type != ConnectionType.TILE:
                continue

            cell_name, pin = ep.pin.split("_", maxsplit=1)
            cell_type = cell_name[:-1]
            # FIXME: The above will fail on cell with index >= 10

            if cell_type in special_tile_loc:
                loc = special_tile_loc[cell_type]

                eps[j] = ConnectionLoc(
                    loc=loc,
                    pin=ep.pin,
                    type=ep.type,
                )

        # Modify the connection
        vpr_connections[i] = Connection(
            src=eps[0], dst=eps[1], is_direct=connection.is_direct
        )

    # handle RAM and MULT locations
    ram_locations = {}
    mult_locations = {}
    for loc, tile in vpr_tile_grid.items():
        if tile is None:
            continue
        cell = tile.cells[0]
        cell_name = cell.name
        if tile.type == "RAM":
            ram_locations[cell_name] = loc
        if tile.type == "MULT":
            mult_locations[cell_name] = loc

    for i, connection in enumerate(vpr_connections):
        # Process connection endpoints
        eps = [connection.src, connection.dst]
        for j, ep in enumerate(eps):

            if ep.type != ConnectionType.TILE:
                continue

            cell_name, pin = ep.pin.split("_", maxsplit=1)
            cell_type = cell_name[:-1]
            # FIXME: The above will fail on cell with index >= 10

            # We handle on MULT and RAM here
            if cell_type != "MULT" and cell_type != "RAM":
                continue

            loc = loc_map.bwd[ep.loc]
            tile = phy_tile_grid[loc]
            cell = [cell for cell in tile.cells if cell.type == cell_type]

            cell_name = cell[0].name

            if cell_type == "MULT":
                loc = mult_locations[cell_name]
            else:
                loc = ram_locations[cell_name]

            eps[j] = ConnectionLoc(
                loc=loc,
                pin=ep.pin,
                type=ep.type,
            )

        # Modify the connection
        vpr_connections[i] = Connection(
            src=eps[0], dst=eps[1], is_direct=connection.is_direct
        )

    # A QMUX should have 3 QCLKIN inputs but accorting to the EOS S3/PP3E
    # techfile it has only one. It is assumed then when "QCLKIN0=GMUX_1" then
    # "QCLKIN1=GMUX_2" etc.
    new_qmux_connections = []
    for connection in vpr_connections:

        # Get only those that target QCLKIN0 of a QMUX.
        if connection.dst.type != ConnectionType.CLOCK:
            continue
        if connection.src.type != ConnectionType.TILE:
            continue

        dst_cell_name, dst_pin = connection.dst.pin.split(".", maxsplit=1)
        if not dst_cell_name.startswith("QMUX") or dst_pin != "QCLKIN0":
            continue

        src_cell_name, src_pin = connection.src.pin.split("_", maxsplit=1)
        if not src_cell_name.startswith("GMUX"):
            continue

        # Add two new connections for QCLKIN1 and QCLKIN2.
        # GMUX connections are already spread along the Z axis so the Z
        # coordinate indicates the GMUX cell index.
        gmux_base = connection.src.loc.z
        for i in [1, 2]:
            gmux_idx = (gmux_base + i) % 5

            c = Connection(
                src=ConnectionLoc(
                    loc=Loc(
                        x=connection.src.loc.x,
                        y=connection.src.loc.y,
                        z=gmux_idx
                    ),
                    pin="GMUX0_IZ",
                    type=connection.src.type
                ),
                dst=ConnectionLoc(
                    loc=connection.dst.loc,
                    pin="{}.QCLKIN{}".format(dst_cell_name, i),
                    type=connection.dst.type
                ),
                is_direct=connection.is_direct
            )
            new_qmux_connections.append(c)

    vpr_connections.extend(new_qmux_connections)

    # Handle QMUX connections. Instead of making them SWITCHBOX -> TILE convert
    # to SWITCHBOX -> CLOCK
    for i, connection in enumerate(vpr_connections):

        # Process connection endpoints
        eps = [connection.src, connection.dst]
        for j, ep in enumerate(eps):

            if ep.type != ConnectionType.TILE:
                continue

            cell_name, pin = ep.pin.split("_", maxsplit=1)

            cell_index = int(cell_name[-1])
            cell_type = cell_name[:-1]
            # FIXME: The above will fail on cell with index >= 10

            # Only QMUX
            if cell_type != "QMUX":
                continue

            # Get the physical tile
            loc = loc_map.bwd[ep.loc]
            tile = phy_tile_grid[loc]

            # Find the cell in the tile
            cells = [
                c for c in tile.cells
                if c.type == "QMUX" and c.index == cell_index
            ]
            assert len(cells) == 1
            cell = cells[0]

            # Modify the endpoint
            eps[j] = ConnectionLoc(
                loc=ep.loc,
                pin="{}.{}".format(cell.name, pin),
                type=ConnectionType.CLOCK,
            )

        # Modify the connection
        vpr_connections[i] = Connection(
            src=eps[0], dst=eps[1], is_direct=connection.is_direct
        )

    return vpr_connections


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


def process_package_pinmap(package_pinmap, vpr_tile_grid, grid_limit=None):
    """
    Processes the package pinmap. Reloacted pin mappings. Reject mappings
    that lie outside the grid limit.
    """

    # Remap locations, reject cells that are either ignored or not in the
    # tilegrid.
    new_package_pinmap = defaultdict(lambda: [])

    for pin_name, pins in package_pinmap.items():
        for pin in pins:

            # The loc is outside the grid limit, skip it.
            if not is_loc_within_limit(pin.loc, grid_limit):
                continue

            # Ignore this one
            if pin.cell.type in IGNORED_IO_CELL_TYPES:
                continue

            # Find the cell
            loc = get_loc_of_cell(pin.cell.name, vpr_tile_grid)
            if loc is None:
                continue

            cell = find_cell_in_tile(pin.cell.name, vpr_tile_grid[loc])
            assert cell is not None, (loc, pin)

            # Remap location
            new_package_pinmap[pin.name].append(
                PackagePin(name=pin.name, alias=pin.alias, loc=loc, cell=cell)
            )

    # Convert to regular dict
    new_package_pinmap = dict(**new_package_pinmap)

    return new_package_pinmap


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


def build_switch_list():
    """
    Builds a list of all switch types used by the architecture
    """
    switches = {}

    # Add a generic mux switch to make VPR happy
    switch = VprSwitch(
        name="generic",
        type="mux",
        t_del=1e-15,  # A deliberate dummy small delay
        r=0.0,
        c_in=0.0,
        c_out=0.0,
        c_int=0.0,
    )
    switches[switch.name] = switch

    # A delayless short
    switch = VprSwitch(
        name="short",
        type="short",
        t_del=0.0,
        r=0.0,
        c_in=0.0,
        c_out=0.0,
        c_int=0.0,
    )
    switches[switch.name] = switch

    return switches


def build_segment_list():
    """
    Builds a list of all segment types used by the architecture
    """
    segments = {}

    # A generic segment
    segment = VprSegment(
        name="generic",
        length=1,
        r_metal=0.0,
        c_metal=0.0,
    )
    segments[segment.name] = segment

    # Padding segment
    segment = VprSegment(
        name="pad",
        length=1,
        r_metal=0.0,
        c_metal=0.0,
    )
    segments[segment.name] = segment

    # Switchbox segment
    segment = VprSegment(
        name="sbox",
        length=1,
        r_metal=0.0,
        c_metal=0.0,
    )
    segments[segment.name] = segment

    # VCC and GND segments
    for const in ["VCC", "GND"]:
        segment = VprSegment(
            name=const.lower(),
            length=1,
            r_metal=0.0,
            c_metal=0.0,
        )
        segments[segment.name] = segment

    # HOP wire segments
    for i in [1, 2, 3, 4]:
        segment = VprSegment(
            name="hop{}".format(i),
            length=i,
            r_metal=0.0,
            c_metal=0.0,
        )
        segments[segment.name] = segment

    # Global clock network segment
    segment = VprSegment(
        name="clock",
        length=1,
        r_metal=0.0,
        c_metal=0.0,
    )
    segments[segment.name] = segment

    # A segment for "hop" connections to "special" tiles.
    segment = VprSegment(
        name="special",
        length=1,
        r_metal=0.0,
        c_metal=0.0,
    )
    segments[segment.name] = segment

    return segments


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


def load_sdf_timings(sdf_dir):
    """
    Loads and merges SDF timing data from all *.sdf files in the given
    directory.
    """

    def apply_scale(cells, scale=1.0):
        """
        Scales all timings represented by the given SDF structure.
        """
        for cell_type, cell_data in cells.items():
            for instance, instance_data in cell_data.items():
                for timing, timing_data in instance_data.items():
                    paths = timing_data["delay_paths"]
                    for path_name, path_data in paths.items():

                        for k in path_data.keys():
                            if path_data[k] is not None:
                                path_data[k] *= scale

    # List SDF files
    files = [f for f in os.listdir(sdf_dir) if f.lower().endswith(".sdf")]

    # Read and parse
    cell_timings = {}

    for f in files:
        print("Loading SDF: '{}'".format(f))

        # Read
        fname = os.path.join(sdf_dir, f)
        with open(fname, "r") as fp:
            sdf = sdfparse.parse(fp.read())

            # Get the timing scale
            header = sdf["header"]
            if "timescale" in header:
                timescale = get_scale_seconds(header["timescale"])
            else:
                print("WARNING: the SDF has no timescale, assuming 1.0")
                timescale = 1.0

            # Apply the scale and update cells
            cells = sdf["cells"]
            apply_scale(cells, timescale)

            cell_timings.update(cells)

    return cell_timings


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


def main():

    # Parse arguments
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter
    )

    parser.add_argument(
        "--phy-db",
        type=str,
        required=True,
        help="Input physical device database file"
    )
    parser.add_argument(
        "--sdf-dir",
        type=str,
        default=None,
        help="A directory with SDF timing files"
    )
    parser.add_argument(
        "--vpr-db",
        type=str,
        default="vpr_database.pickle",
        help="Output VPR database file"
    )
    parser.add_argument(
        "--grid-limit",
        type=str,
        default=None,
        help="Grid coordinate range to import eg. '0,0,10,10' (def. None)"
    )

    args = parser.parse_args()

    # Grid limit
    if args.grid_limit is not None:
        grid_limit = [int(q) for q in args.grid_limit.split(",")]
    else:
        grid_limit = None

    # Load data from the database
    with open(args.phy_db, "rb") as fp:
        db = pickle.load(fp)

        phy_quadrants = db["phy_quadrants"]
        cells_library = db["cells_library"]
        tile_types = db["tile_types"]
        phy_tile_grid = db["phy_tile_grid"]
        phy_clock_cells = db["phy_clock_cells"]
        switchbox_types = db["switchbox_types"]
        phy_switchbox_grid = db["switchbox_grid"]
        switchbox_timing = db["switchbox_timing"]
        connections = db["connections"]
        package_pinmaps = db["package_pinmaps"]

    # Load and parse SDF files
    if args.sdf_dir is not None:
        cell_timings = load_sdf_timings(args.sdf_dir)
    else:
        cell_timings = None

    # Process the cells library
    vpr_cells_library = process_cells_library(cells_library)

    # Add synthetic stuff
    add_synthetic_cell_and_tile_types(tile_types, vpr_cells_library)

    # Determine the grid offset so occupied locations start at GRID_MARGIN
    tl_min = min([loc.x for loc in phy_tile_grid]), min(
        [loc.y for loc in phy_tile_grid]
    )
    tl_max = max([loc.x for loc in phy_tile_grid]), max(
        [loc.y for loc in phy_tile_grid]
    )

    sb_min = min([loc.x for loc in phy_switchbox_grid]), min(
        [loc.y for loc in phy_switchbox_grid]
    )
    sb_max = max([loc.x for loc in phy_switchbox_grid]), max(
        [loc.y for loc in phy_switchbox_grid]
    )

    grid_min = min(tl_min[0], sb_min[0]), min(tl_min[1], sb_min[1])
    grid_max = max(tl_max[0], sb_max[0]), max(tl_max[1], sb_max[1])

    # Compute VPR grid offset w.r.t the physical grid and its size
    grid_offset = GRID_MARGIN[0] - grid_min[0], GRID_MARGIN[1] - grid_min[1]

    grid_size = GRID_MARGIN[0] + GRID_MARGIN[2] + (
        grid_max[0] - grid_min[0] + 1
    ), GRID_MARGIN[1] + GRID_MARGIN[3] + (
        grid_max[1] - grid_min[1] + 1
    )

    # Remap quadrant locations
    vpr_quadrants = {}
    for quadrant in phy_quadrants.values():
        vpr_quadrants[quadrant.name] = Quadrant(
            name=quadrant.name,
            x0=quadrant.x0 + grid_offset[0],
            x1=quadrant.x1 + grid_offset[0],
            y0=quadrant.y0 + grid_offset[1],
            y1=quadrant.y1 + grid_offset[1]
        )

    # Process the tilegrid
    vpr_tile_grid, vpr_clock_cells, loc_map = process_tilegrid(
        tile_types, phy_tile_grid, phy_clock_cells, vpr_cells_library,
        grid_size, grid_offset, grid_limit
    )

    # Process the switchbox grid
    vpr_switchbox_grid, loc_map = process_switchbox_grid(
        phy_switchbox_grid, loc_map, grid_offset, grid_limit
    )

    # Process connections
    connections = process_connections(
        connections, loc_map, vpr_tile_grid, phy_tile_grid, grid_limit
    )

    # Process package pinmaps
    vpr_package_pinmaps = {}
    for package, pkg_pin_map in package_pinmaps.items():
        vpr_package_pinmaps[package] = process_package_pinmap(
            pkg_pin_map, vpr_tile_grid, grid_limit
        )

    # Get tile types present in the grid
    vpr_tile_types = set(
        [t.type for t in vpr_tile_grid.values() if t is not None]
    )
    vpr_tile_types = {
        k: v
        for k, v in tile_types.items()
        if k in vpr_tile_types
    }

    # Get the switchbox types present in the grid
    vpr_switchbox_types = set(
        [s for s in vpr_switchbox_grid.values() if s is not None]
    )
    vpr_switchbox_types = {
        k: v
        for k, v in switchbox_types.items()
        if k in vpr_switchbox_types
    }

    # Make tile -> site equivalence list
    vpr_equivalent_sites = {}

    # Make switch list
    vpr_switches = build_switch_list()
    # Make segment list
    vpr_segments = build_segment_list()

    # Process timing data
    if switchbox_timing is not None or cell_timings is not None:
        print("Processing timing data...")

    if switchbox_timing is not None:

        # The timing data seems to be the same for each switchbox type and is
        # stored under the SB_LC name.
        timing_data = switchbox_timing["SB_LC"]

        # Compute the timing model for the most generic SB_LC switchbox.
        switchbox = vpr_switchbox_types["SB_LC"]
        driver_timing, sink_map = compute_switchbox_timing_model(
            switchbox, timing_data
        )

        # Populate the model, create and assign VPR switches.
        populate_switchbox_timing(
            switchbox, driver_timing, sink_map, vpr_switches
        )

        # Propagate the timing data to all other switchboxes. Even though they
        # are of different type, physically they are the same.
        for dst_switchbox in vpr_switchbox_types.values():
            if dst_switchbox.type != "SB_LC":
                copy_switchbox_timing(switchbox, dst_switchbox)

    if cell_timings is not None:

        sw = add_vpr_switches_for_cell("QMUX", cell_timings)
        vpr_switches.update(sw)

        sw = add_vpr_switches_for_cell("CAND", cell_timings)
        vpr_switches.update(sw)

    if DEBUG:
        # DBEUG
        print("Tile grid:")
        xmax = max([loc.x for loc in vpr_tile_grid])
        ymax = max([loc.y for loc in vpr_tile_grid])
        for y in range(ymax + 1):
            line = " {:>2}: ".format(y)
            for x in range(xmax + 1):
                loc = Loc(x=x, y=y, z=0)
                if loc not in vpr_tile_grid:
                    line += " "
                elif vpr_tile_grid[loc] is not None:
                    tile_type = vpr_tile_types[vpr_tile_grid[loc].type]
                    label = sorted(list(tile_type.cells.keys()))[0][0].upper()
                    line += label
                else:
                    line += "."
            print(line)

        # DBEUG
        print("Tile capacity / sub-tile count")
        xmax = max([loc.x for loc in vpr_tile_grid])
        ymax = max([loc.y for loc in vpr_tile_grid])
        for y in range(ymax + 1):
            line = " {:>2}: ".format(y)
            for x in range(xmax + 1):

                tiles = {
                    loc: tile
                    for loc, tile in vpr_tile_grid.items()
                    if loc.x == x and loc.y == y
                }
                count = len([t for t in tiles.values() if t is not None])

                if len(tiles) == 0:
                    line += " "
                elif count == 0:
                    line += "."
                else:
                    line += "{:X}".format(count)

            print(line)

        # DEBUG
        print("Switchbox grid:")
        xmax = max([loc.x for loc in vpr_switchbox_grid])
        ymax = max([loc.y for loc in vpr_switchbox_grid])
        for y in range(ymax + 1):
            line = " {:>2}: ".format(y)
            for x in range(xmax + 1):
                loc = Loc(x=x, y=y, z=0)
                if loc not in vpr_switchbox_grid:
                    line += " "
                elif vpr_switchbox_grid[loc] is not None:
                    line += "X"
                else:
                    line += "."
            print(line)

        # DBEUG
        print("Route-through global clock cells:")
        xmax = max([loc.x for loc in vpr_tile_grid])
        ymax = max([loc.y for loc in vpr_tile_grid])
        for y in range(ymax + 1):
            line = " {:>2}: ".format(y)
            for x in range(xmax + 1):
                loc = Loc(x=x, y=y, z=0)

                for cell in vpr_clock_cells.values():
                    if cell.loc == loc:
                        line += cell.name[0].upper()
                        break
                else:
                    line += "."
            print(line)

        # DEBUG
        print("VPR Segments:")
        for s in vpr_segments.values():
            print("", s)

        # DEBUG
        print("VPR Switches:")
        for s in vpr_switches.values():
            print("", s)

    # Prepare the VPR database and write it
    db_root = {
        "vpr_cells_library": vpr_cells_library,
        "loc_map": loc_map,
        "vpr_quadrants": vpr_quadrants,
        "vpr_tile_types": vpr_tile_types,
        "vpr_tile_grid": vpr_tile_grid,
        "vpr_clock_cells": vpr_clock_cells,
        "vpr_equivalent_sites": vpr_equivalent_sites,
        "vpr_switchbox_types": vpr_switchbox_types,
        "vpr_switchbox_grid": vpr_switchbox_grid,
        "connections": connections,
        "vpr_package_pinmaps": vpr_package_pinmaps,
        "segments": list(vpr_segments.values()),
        "switches": list(vpr_switches.values()),
    }

    with open("{}.tmp".format(args.vpr_db), "wb") as fp:
        pickle.dump(db_root, fp, protocol=3)

    os.rename("{}.tmp".format(args.vpr_db), args.vpr_db)


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

if __name__ == "__main__":
    main()
