#!/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 os
import argparse
import pickle
from collections import OrderedDict

import lxml.etree as ET

from f4pga.utils.quicklogic.pp3.data_structs import ConnectionType, Loc

from f4pga.utils.quicklogic.pp3.tile_import import make_top_level_pb_type
from f4pga.utils.quicklogic.pp3.tile_import import make_top_level_tile

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


def is_direct(connection):
    """
    Returns True if the connections spans two tiles directly. Not necessarly
    at the same location
    """

    if (
        connection.src.type == ConnectionType.TILE
        and connection.dst.type == ConnectionType.TILE
        and connection.is_direct is True
    ):
        return True

    return False


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


def add_segment(xml_parent, segment):
    """
    Adds a segment
    """

    segment_type = "bidir"

    # Make XML
    xml_seg = ET.SubElement(
        xml_parent,
        "segment",
        {
            "name": segment.name,
            "length": str(segment.length),
            "freq": "1.0",
            "type": segment_type,
            "Rmetal": str(segment.r_metal),
            "Cmetal": str(segment.c_metal),
        },
    )

    if segment_type == "unidir":
        ET.SubElement(xml_seg, "mux", {"name": "generic"})

    elif segment_type == "bidir":
        ET.SubElement(xml_seg, "wire_switch", {"name": "generic"})
        ET.SubElement(xml_seg, "opin_switch", {"name": "generic"})

    else:
        assert False, segment_type

    e = ET.SubElement(xml_seg, "sb", {"type": "pattern"})
    e.text = " ".join(["1" for i in range(segment.length + 1)])
    e = ET.SubElement(xml_seg, "cb", {"type": "pattern"})
    e.text = " ".join(["1" for i in range(segment.length)])


def add_switch(xml_parent, switch):
    """
    Adds a switch
    """

    xml_switch = ET.SubElement(
        xml_parent,
        "switch",
        {
            "type": switch.type,
            "name": switch.name,
            "R": str(switch.r),
            "Cin": str(switch.c_in),
            "Cout": str(switch.c_out),
            "Tdel": str(switch.t_del),
        },
    )

    if switch.type in ["mux", "tristate"]:
        xml_switch.attrib["Cinternal"] = str(switch.c_int)


def initialize_arch(xml_arch, switches, segments):
    """
    Initializes the architecture definition from scratch.
    """

    # .................................
    # Device
    xml_device = ET.SubElement(xml_arch, "device")

    ET.SubElement(
        xml_device,
        "sizing",
        {
            "R_minW_nmos": "6000.0",
            "R_minW_pmos": "18000.0",
        },
    )

    ET.SubElement(xml_device, "area", {"grid_logic_tile_area": "15000.0"})

    xml = ET.SubElement(xml_device, "chan_width_distr")
    ET.SubElement(xml, "x", {"distr": "uniform", "peak": "1.0"})
    ET.SubElement(xml, "y", {"distr": "uniform", "peak": "1.0"})

    ET.SubElement(xml_device, "connection_block", {"input_switch_name": "generic"})

    ET.SubElement(
        xml_device,
        "switch_block",
        {
            "type": "wilton",
            "fs": "3",
        },
    )

    ET.SubElement(
        xml_device,
        "default_fc",
        {
            "in_type": "frac",
            "in_val": "1.0",
            "out_type": "frac",
            "out_val": "1.0",
        },
    )

    # .................................
    # Switchlist
    xml_switchlist = ET.SubElement(xml_arch, "switchlist")
    got_generic_switch = False

    for switch in switches:
        add_switch(xml_switchlist, switch)

        # Check for the generic switch
        if switch.name == "generic":
            got_generic_switch = True

    # No generic switch
    assert got_generic_switch

    # .................................
    # Segmentlist
    xml_seglist = ET.SubElement(xml_arch, "segmentlist")

    for segment in segments:
        add_segment(xml_seglist, segment)


def write_tiles(xml_arch, arch_tile_types, tile_types, equivalent_sites):
    """
    Generates the "tiles" section of the architecture file
    """

    # The "tiles" section
    xml_tiles = xml_arch.find("tiles")
    if xml_tiles is None:
        xml_tiles = ET.SubElement(xml_arch, "tiles")

    # Add tiles
    for tile_type, sub_tiles in arch_tile_types.items():

        xml = make_top_level_tile(tile_type, sub_tiles, tile_types, equivalent_sites)

        xml_tiles.append(xml)


def write_pb_types(xml_arch, arch_pb_types, tile_types, nsmap):
    """
    Generates the "complexblocklist" section.
    """

    # Complexblocklist
    xml_cplx = xml_arch.find("complexblocklist")
    if xml_cplx is None:
        xml_cplx = ET.SubElement(xml_arch, "complexblocklist")

    # Add pb_types
    for pb_type in arch_pb_types:

        xml = make_top_level_pb_type(tile_types[pb_type], nsmap)
        xml_cplx.append(xml)


def write_models(xml_arch, arch_models, nsmap):
    """
    Generates the "models" section.
    """

    # Models
    xml_models = xml_arch.find("models")
    if xml_models is None:
        xml_models = ET.SubElement(xml_arch, "models")

    # Include cell models
    xi_include = "{{{}}}include".format(nsmap["xi"])
    for model in arch_models:
        name = model.lower()

        # Be smart. Check if there is a file for that cell in the current
        # directory. If not then use the one from "primitives" path
        model_file = "./{}.model.xml".format(name)
        if not os.path.isfile(model_file):
            model_file = "../../primitives/{}/{}.model.xml".format(name, name)

        ET.SubElement(
            xml_models,
            xi_include,
            {
                "href": model_file,
                "xpointer": "xpointer(models/child::node())",
            },
        )


def write_tilegrid(xml_arch, arch_tile_grid, loc_map, layout_name):
    """
    Generates the "layout" section of the arch XML and appends it to the
    root given.
    """

    # Remove the "layout" tag if any
    xml_layout = xml_arch.find("layout")
    if xml_layout is not None:
        xml_arch.remove(xml_layout)

    # Grid size
    xs = [flat_loc[0] for flat_loc in arch_tile_grid]
    ys = [flat_loc[1] for flat_loc in arch_tile_grid]
    w = max(xs) + 1
    h = max(ys) + 1

    # Fixed layout
    xml_layout = ET.SubElement(xml_arch, "layout")
    xml_fixed = ET.SubElement(
        xml_layout,
        "fixed_layout",
        {
            "name": layout_name,
            "width": str(w),
            "height": str(h),
        },
    )

    # Individual tiles
    for flat_loc, tile in arch_tile_grid.items():

        if tile is None:
            continue

        # Unpack
        tile_type, capacity = tile

        # Single tile
        xml_sing = ET.SubElement(
            xml_fixed,
            "single",
            {
                "type": "TL-{}".format(tile_type.upper()),
                "x": str(flat_loc[0]),
                "y": str(flat_loc[1]),
                "priority": str(10),  # Not sure if we need this
            },
        )

        # Gather metadata
        metadata = []
        for i in range(capacity):
            loc = Loc(x=flat_loc[0], y=flat_loc[1], z=i)

            if loc in loc_map.bwd:
                phy_loc = loc_map.bwd[loc]
                metadata.append("X{}Y{}".format(phy_loc.x, phy_loc.y))

        # Emit metadata if any
        if len(metadata):
            xml_metadata = ET.SubElement(xml_sing, "metadata")
            xml_meta = ET.SubElement(
                xml_metadata,
                "meta",
                {
                    "name": "fasm_prefix",
                },
            )
            xml_meta.text = " ".join(metadata)


def write_direct_connections(xml_arch, tile_grid, connections):
    """ """

    def get_tile(ep):
        """
        Retireves tile for the given connection endpoint
        """

        if ep.loc in tile_grid and tile_grid[ep.loc] is not None:
            return tile_grid[ep.loc]

        else:
            print("ERROR: No tile found for the connection endpoint", ep)
            return None

    # Remove the "directlist" tag if any
    xml_directlist = xml_arch.find("directlist")
    if xml_directlist is not None:
        xml_arch.remove(xml_directlist)

    # Make a new one
    xml_directlist = ET.SubElement(xml_arch, "directlist")

    # Populate connections
    conns = [c for c in connections if is_direct(c)]
    for connection in conns:

        src_tile = get_tile(connection.src)
        dst_tile = get_tile(connection.dst)

        if not src_tile or not dst_tile:
            continue

        src_name = "TL-{}.{}".format(src_tile.type, connection.src.pin)
        dst_name = "TL-{}.{}".format(dst_tile.type, connection.dst.pin)

        name = "{}_at_X{}Y{}Z{}_to_{}_at_X{}Y{}Z{}".format(
            src_name,
            connection.src.loc.x,
            connection.src.loc.y,
            connection.src.loc.z,
            dst_name,
            connection.dst.loc.x,
            connection.dst.loc.y,
            connection.dst.loc.z,
        )

        delta_loc = Loc(
            x=connection.dst.loc.x - connection.src.loc.x,
            y=connection.dst.loc.y - connection.src.loc.y,
            z=connection.dst.loc.z - connection.src.loc.z,
        )

        # Format the direct connection tag
        ET.SubElement(
            xml_directlist,
            "direct",
            {
                "name": name,
                "from_pin": src_name,
                "to_pin": dst_name,
                "x_offset": str(delta_loc.x),
                "y_offset": str(delta_loc.y),
                "z_offset": str(delta_loc.z),
            },
        )


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


def main():

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

    parser.add_argument("--vpr-db", type=str, required=True, help="VPR database file")
    parser.add_argument("--arch-out", type=str, default="arch.xml", help="Output arch XML file (def. arch.xml)")
    parser.add_argument("--device", type=str, default="quicklogic", help="Device name for the architecture")

    args = parser.parse_args()

    xi_url = "http://www.w3.org/2001/XInclude"
    ET.register_namespace("xi", xi_url)
    nsmap = {"xi": xi_url}

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

        loc_map = db["loc_map"]
        vpr_tile_types = db["vpr_tile_types"]
        vpr_tile_grid = db["vpr_tile_grid"]
        vpr_equivalent_sites = db["vpr_equivalent_sites"]
        segments = db["segments"]
        switches = db["switches"]
        connections = db["connections"]

    # Flatten the VPR tilegrid
    flat_tile_grid = dict()
    for vpr_loc, tile in vpr_tile_grid.items():

        flat_loc = (vpr_loc.x, vpr_loc.y)
        if flat_loc not in flat_tile_grid:
            flat_tile_grid[flat_loc] = {}

        if tile is not None:
            flat_tile_grid[flat_loc][vpr_loc.z] = tile.type

    # Create the arch tile grid and arch tile types
    arch_tile_grid = dict()
    arch_tile_types = dict()
    arch_pb_types = set()
    arch_models = set()

    for flat_loc, tiles in flat_tile_grid.items():

        if len(tiles):

            # Group identical sub-tiles together, maintain their order
            sub_tiles = OrderedDict()
            for z, tile in tiles.items():
                if tile not in sub_tiles:
                    sub_tiles[tile] = 0
                sub_tiles[tile] += 1

            # TODO: Make arch tile type name
            tile_type = tiles[0]

            # Create the tile type with sub tile types for the arch
            arch_tile_types[tile_type] = sub_tiles

            # Add each sub-tile to top-level pb_type list
            for tile in sub_tiles:
                arch_pb_types.add(tile)

            # Add each cell of a sub-tile to the model list
            for tile in sub_tiles:
                for cell_type in vpr_tile_types[tile].cells.keys():
                    arch_models.add(cell_type)

            # Add the arch tile type to the arch tile grid
            arch_tile_grid[flat_loc] = (
                tile_type,
                len(tiles),
            )

        else:

            # Add an empty location
            arch_tile_grid[flat_loc] = None

    # Initialize the arch XML if file not given
    xml_arch = ET.Element("architecture", nsmap=nsmap)
    initialize_arch(xml_arch, switches, segments)

    # Add tiles
    write_tiles(xml_arch, arch_tile_types, vpr_tile_types, vpr_equivalent_sites)
    # Add pb_types
    write_pb_types(xml_arch, arch_pb_types, vpr_tile_types, nsmap)
    # Add models
    write_models(xml_arch, arch_models, nsmap)

    # Write the tilegrid to arch
    write_tilegrid(xml_arch, arch_tile_grid, loc_map, args.device)

    # Write direct connections
    write_direct_connections(xml_arch, vpr_tile_grid, connections)

    # Save the arch
    ET.ElementTree(xml_arch).write(args.arch_out, pretty_print=True, xml_declaration=True, encoding="utf-8")


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

if __name__ == "__main__":
    main()
