#!/usr/bin/env python3

import sys, os, json


class MergeFind:
    def __init__(self):
        self.db = dict()

    def merge(self, a, b):
        a = self.find(a)
        b = self.find(b)
        if a != b:
            self.db[a] = b

    def find(self, a):
        if a in self.db:
            c = self.find(self.db[a])
            self.db[a] = c
            return c
        return a


print("Reading database..")

with open("%s/%s/tilegrid.json" % (os.getenv("XRAY_DATABASE_DIR"),
                                   os.getenv("XRAY_DATABASE")), "r") as f:
    tiles = json.load(f)["tiles"]

with open("%s/%s/tileconn.json" % (os.getenv("XRAY_DATABASE_DIR"),
                                   os.getenv("XRAY_DATABASE")), "r") as f:
    tileconn = json.load(f)

type_to_tiles = dict()
grid_to_tile = dict()
nodes = MergeFind()

for tile, tiledata in tiles.items():
    if tiledata["type"] not in type_to_tiles:
        type_to_tiles[tiledata["type"]] = list()
    type_to_tiles[tiledata["type"]].append(tile)
    grid_to_tile[(tiledata["grid_x"], tiledata["grid_y"])] = tile

print("Processing tileconn..")

for entry in tileconn:
    type_a, type_b = entry["tile_types"]
    for tile_a in type_to_tiles[type_a]:
        tiledata_a = tiles[tile_a]
        grid_a = (tiledata_a["grid_x"], tiledata_a["grid_y"])
        grid_b = (
            grid_a[0] + entry["grid_deltas"][0],
            grid_a[1] + entry["grid_deltas"][1])

        if grid_b not in grid_to_tile:
            continue

        tile_b = grid_to_tile[grid_b]
        tiledata_b = tiles[tile_b]

        if tiledata_b["type"] != type_b:
            continue

        for pair in entry["wire_pairs"]:
            nodes.merge((tile_a, pair[0]), (tile_b, pair[1]))

print("Processing PIPs..")

node_node_pip = dict()
reverse_node_node = dict()

for tile_type in ["int_l", "int_r"]:
    with open("%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"),
                                       os.getenv("XRAY_DATABASE"), tile_type),
              "r") as f:
        for line in f:
            _, dst, src = line.split()[0].split(".")
            for tile in type_to_tiles[tile_type.upper()]:
                src_node = nodes.find((tile, src))
                dst_node = nodes.find((tile, dst))
                if src_node not in node_node_pip:
                    node_node_pip[src_node] = dict()
                if dst_node not in reverse_node_node:
                    reverse_node_node[dst_node] = set()
                node_node_pip[src_node][dst_node] = "%s.%s.%s" % (
                    tile, dst, src)
                reverse_node_node[dst_node].add(src_node)


def route(args):
    active_pips = set()
    blocked_nodes = set()

    for argidx in range((len(args)) // 2):
        src_tile, src_wire = args[2 * argidx].split("/")
        dst_tile, dst_wire = args[2 * argidx + 1].split("/")

        src_node = nodes.find((src_tile, src_wire))
        dst_node = nodes.find((dst_tile, dst_wire))

        print("Routing %s -> %s:" % (src_node, dst_node))

        node_scores = dict()

        def write_scores(nodes, count):
            next_nodes = set()
            for n in nodes:
                if n in node_scores:
                    continue
                node_scores[n] = count
                if n == src_node:
                    return
                if n in reverse_node_node:
                    for nn in reverse_node_node[n]:
                        if nn not in node_scores and nn not in blocked_nodes:
                            next_nodes.add(nn)
            write_scores(next_nodes, count + 1)

        try:
            write_scores(set([dst_node]), 1)
        except RecursionError as e:
            raise Exception("Could not find route for node %s" % (dst_node,)) from None
        print("  route length: %d" % node_scores[src_node])

        count = 0
        c = src_node
        blocked_nodes.add(c)
        print("  %4d: %s" % (count, c))

        score = node_scores[src_node]
        while c != dst_node:
            nn = None
            for n in node_node_pip[c].keys():
                if n in node_scores and node_scores[n] < score:
                    nn, score = n, node_scores[n]

            pip = node_node_pip[c][nn]
            active_pips.add(pip)
            print("        %s" % pip)

            count += 1
            c = nn
            blocked_nodes.add(c)
            print("  %4d: %s" % (count, c))

    print("====")
    pipnames = list()

    for pip in sorted(active_pips):
        tile, dst, src = pip.split(".")
        pipnames.append("%s/%s.%s->>%s" % (tile, tile[0:5], src, dst))

    print(
        "highlight_objects -color orange [get_nodes -of_objects [get_wires {%s}]]"
        % " ".join(["%s/%s" % n for n in sorted(blocked_nodes)]))
    print(
        "highlight_objects -color orange [get_pips {%s}]" % " ".join(pipnames))

    print("====")
    for pip in sorted(active_pips):
        print(pip)
    return active_pips


if __name__ == '__main__':
    if len(sys.argv) == 1 or (len(sys.argv) % 2) != 1:
        print()
        print("Usage: %s src1 dst1 [src2 dst2 [...]]" % sys.argv[0])
        print("Where entires as tile/wire")
        print()
        print(
            "Example: %s VBRK_X29Y140/VBRK_ER1BEG2 VFRAME_X47Y113/VFRAME_EL1BEG2"
            % sys.argv[0])
        print()
        sys.exit(1)
    route(sys.argv[1:])
