#!/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
"""
This file implements a simple graph router used for complex block routing
graphs.
"""

import logging

from f4pga.utils.quicklogic.repacker.pb_rr_graph import NodeType

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


class Net:
    """
    This class represents a net for the router. It holds the driver (source)
    node as well as all sink node ids.
    """

    def __init__(self, name):
        self.name = name

        self.sources = set()
        self.sinks = set()

        self.is_routed = False

    def __str__(self):
        return "{}, {} sources, max_fanout={}, {}".format(
            self.name, len(self.sources), len(self.sinks), "routed" if self.is_routed else "unrouted"
        )


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


class Router:
    """
    Simple graph router.

    Currently the routed does a greedy depth-first routing. Each time a path
    from a sink to a source is found it gets immediately annotated with nets.
    """

    def __init__(self, graph):
        self.graph = graph
        self.nets = {}

        # Discover nets from the graph
        self.discover_nets()

    def discover_nets(self):
        """
        Scans the graph looking for nets
        """

        # TODO: For now look for nets only assuming that all of them are
        # unrouted.
        sources = {}
        sinks = {}

        for node in self.graph.nodes.values():
            if node.type not in [NodeType.SOURCE, NodeType.SINK]:
                continue

            # No net
            if node.net is None:
                continue

            # Got a source
            if node.type == NodeType.SOURCE:
                if node.net not in sources:
                    sources[node.net] = set()
                sources[node.net].add(node.id)

            # Got a sink
            elif node.type == NodeType.SINK:
                if node.net not in sinks:
                    sinks[node.net] = set()
                sinks[node.net].add(node.id)

        # Make nets
        nets = set(sinks.keys()) | set(sources.keys())
        for net_name in nets:
            net = Net(net_name)

            # A net may or may not have a source node(s). If there are no
            # sources then one will be created during routing when a route
            # reaches a node of the top-level CLB.
            if net_name in sources:
                net.sources = sources[net_name]

            # A net may or may not have at leas one sink node. If there are
            # no sinks then no routing will be done.
            if net_name in sinks:
                net.sinks = sinks[net_name]

            self.nets[net_name] = net

        # DEBUG
        logging.debug("   Nets:")
        keys = sorted(list(self.nets.keys()))
        for key in keys:
            logging.debug("    " + str(self.nets[key]))

    def route_net(self, net, debug=False):
        """
        Routes a single net.
        """

        top_level_sources = set()

        def walk_depth_first(node, curr_route=None):
            # FIXME: Two possible places for optimization:
            # - create an edge lookup list indexed by dst node ids
            # - do not copy the current route list for each recursion level

            # Track the route
            if not curr_route:
                curr_route = []
            curr_route.append(node.id)

            # We've hit a node of the same net. Finish.
            if node.type in [NodeType.SOURCE, NodeType.PORT]:
                if node.net == net.name:
                    return curr_route

            # The node is aleady occupied by a different net
            if node.net is not None:
                if node.net != net.name:
                    return None

            # This node is a free source node. If it is a top-level source then
            # store it.
            if node.type == NodeType.SOURCE and node.net is None:
                if node.path.count(".") == 1:
                    top_level_sources.add(node.id)

            # Check all incoming edges
            for edge in self.graph.edges:
                if edge.dst_id == node.id:
                    # Recurse
                    next_node = self.graph.nodes[edge.src_id]
                    route = walk_depth_first(next_node, list(curr_route))

                    # We have a route, terminate
                    if route:
                        return route

            return None

        # Search for a route
        logging.debug("   " + net.name)

        # This net has no sinks. Remove annotation from the source nodes
        if not net.sinks:
            for node_id in net.sources:
                node = self.graph.nodes[node_id]
                node.net = None

        # Route all sinks to any of the net sources
        for sink in net.sinks:
            # Find the route
            node = self.graph.nodes[sink]

            top_level_sources = set()
            route = walk_depth_first(node)

            # No route found. Check if we have some free top-level ports that
            # we can use.
            if not route and top_level_sources:
                # Use the frist one
                top_node_id = next(iter(top_level_sources))
                top_node = self.graph.nodes[top_node_id]
                top_node.net = net.name

                # Retry
                route = walk_depth_first(node)

            # No route found
            if not route:
                logging.critical("    No route found!")

                # DEBUG
                if debug:
                    with open("unrouted.dot", "w") as fp:
                        fp.write(self.graph.dump_dot(color_by="net", highlight_nodes=net.sources | set([sink])))

                # Raise an exception
                raise RuntimeError(
                    "Unroutable net '{}' from {} to {}".format(
                        net.name, [self.graph.nodes[node_id] for node_id in net.sources], self.graph.nodes[sink]
                    )
                )

            # Annotate all nodes of the route
            for node_id in route:
                self.graph.nodes[node_id].net = net.name

        # Success
        net.is_routed = True

    def route_nets(self, nets=None, debug=False):
        """
        Routes net with specified names or all nets if no names are given.
        """

        # Use all if explicit list not provided
        if nets is None:
            nets = sorted(list(self.nets.keys()))

        # Route nets
        for net_name in nets:
            self.route_net(self.nets[net_name], debug=debug)
