#!/usr/bin/env python3

import getopt, sys, os, json, re

if len(sys.argv) == 1 or (len(sys.argv) % 2) != 1:
    print()
    print("Usage: %s src1 dst1 [src2 dst2 [...]]" % sys.argv[0])
    print()
    print(
        "Example: %s VBRK_X29Y140/VBRK_ER1BEG2 VFRAME_X47Y113/VFRAME_EL1BEG2" %
        sys.argv[0])
    print()
    sys.exit(1)


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()
blocked_nodes = set()
active_pips = set()

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)

for argidx in range((len(sys.argv) - 1) // 2):
    src_tile, src_wire = sys.argv[2 * argidx + 1].split("/")
    dst_tile, dst_wire = sys.argv[2 * argidx + 2].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)

    write_scores(set([dst_node]), 1)
    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)
