#!/usr/bin/env python3
""" Classify 7-series nodes and generate channels for required nodes.

Rough structure:

Create initial database import by importing tile types, tile wires, tile pips,
site types and site pins.  After importing tile types, imports the grid of
tiles.  This uses tilegrid.json, tile_type_*.json and site_type_*.json.

Once all tiles are imported, all wires in the grid are added and nodes are
formed from the sea of wires based on the tile connections description
(tileconn.json).

In order to determine what each node is used for, site pins and pips are counted
on each node (count_sites_and_pips_on_nodes).  Depending on the site pin and
pip count, the nodes are classified into one of 4 buckets:

    NULL - An unconnected node
    CHANNEL - A routing node
    EDGE_WITH_MUX - An edge between an IPIN and OPIN.
    EDGES_TO_CHANNEL - An edge between an IPIN/OPIN and a CHANNEL.

Then all CHANNEL are grouped into tracks (form_tracks) and graph nodes are
created for the CHANNELs.  Graph edges are added to connect graph nodes that are
part of the same track.

Note that IPIN and OPIN graph nodes are not added yet, as pins have not been
assigned sides of the VPR tiles yet.  This occurs in
prjxray_assign_tile_pin_direction.


"""
import argparse
import csv
import prjxray.db
import prjxray.tile
from prjxray.timing import PvtCorner
from lib import progressbar_utils
import tile_splitter.grid
from lib.rr_graph import points
from lib.rr_graph import tracks
from lib.rr_graph import graph2
import datetime
import os
import os.path
from lib.connection_database import NodeClassification, create_tables, node_to_site_pins

from prjxray_db_cache import DatabaseCache
from prjxray_define_segments import SegmentWireMap

SINGLE_PRECISION_FLOAT_MIN = 2**-126
VCC_NET = 'VCC_NET'
GND_NET = 'GND_NET'


def import_site_type(db, write_cur, site_types, site_type_name):
    assert site_type_name not in site_types
    site_type = db.get_site_type(site_type_name)

    if site_type_name in site_types:
        return

    write_cur.execute(
        "INSERT INTO site_type(name) VALUES (?)", (site_type_name, )
    )
    site_types[site_type_name] = write_cur.lastrowid

    for site_pin in site_type.get_site_pins():
        pin_info = site_type.get_site_pin(site_pin)

        write_cur.execute(
            """
INSERT INTO site_pin(name, site_type_pkey, direction)
VALUES
  (?, ?, ?)""", (
                pin_info.name, site_types[site_type_name],
                pin_info.direction.value
            )
        )


def create_get_switch(conn):
    """ Returns functions to get or create switches with various timing.

    Every switch that requires different timing is given it's own switch
    in VPR.  get_switch returns a switch a pip.  get_switch_timing returns
    a switch given a particular timing.

    """
    write_cur = conn.cursor()

    pip_cache = {}

    write_cur.execute(
        "SELECT pkey FROM switch WHERE name = ?",
        ("__vpr_delayless_switch__", )
    )
    pip_cache[(False, 0.0, 0.0, 0.0)] = write_cur.fetchone()[0]

    def get_switch_timing(
            is_pass_transistor, delay, internal_capacitance, drive_resistance
    ):
        """ Return a switch that matches provided timing.

        Arguments
        ---------
        is_pass_transistor : bool-like
            If true, this switch should be represented as a "pass_gate".

        delay : float or convertable to float
            Intrinsic delay through switch (seconds)

        internal_capacitance : float or convertable to float
            Internal capacitance to switch (Farads).

        drive_resistance : float or convertable to float
            Drive resistance from switch (Ohms).

        Returns
        -------
        switch_pkey : int
            Switch primary key that represents provided arguments.

        """
        key = (
            bool(is_pass_transistor), float(delay), float(drive_resistance),
            float(internal_capacitance)
        )

        if key not in pip_cache:
            name = 'routing'
            switch_type = 'mux'
            if is_pass_transistor:
                name = 'pass_transistor'
                switch_type = 'pass_gate'

            name = '{}_R{}_C{}_Tdel{}'.format(
                name, drive_resistance, internal_capacitance, delay
            )

            write_cur.execute(
                """
INSERT INTO
    switch(
        name, internal_capacitance, drive_resistance, intrinsic_delay, switch_type
    )
VALUES
    (?, ?, ?, ?, ?)""", (
                    name, internal_capacitance, drive_resistance, delay,
                    switch_type
                )
            )
            pip_cache[key] = write_cur.lastrowid

            write_cur.connection.commit()

        return pip_cache[key]

    def get_switch(pip, pip_timing):
        """ Return switch_pkey for given pip timing.

        Arguments
        ---------
        pip : tile.Pip object
            Pip being modelled
        pip_timing : tile.PipTiming object
            Pip timing being modelled

        Returns
        -------
        switch_pkey : int
            Switch primary key that represents provided arguments.

        """
        delay = 0.0
        drive_resistance = 0.0
        internal_capacitance = 0.0

        if pip_timing is not None:
            if pip_timing.delays is not None:
                # Use the largest intristic delay for now.
                # This conservative on slack timing, but not on hold timing.
                #
                # nanosecond -> seconds
                delay = pip_timing.delays[PvtCorner.SLOW].max / 1e9

            if pip_timing.internal_capacitance is not None:
                # microFarads -> Farads
                internal_capacitance = pip_timing.internal_capacitance / 1e6

            if pip_timing.drive_resistance is not None:
                # milliOhms -> Ohms
                drive_resistance = pip_timing.drive_resistance / 1e3

        return get_switch_timing(
            pip.is_pass_transistor, delay, internal_capacitance,
            drive_resistance
        )

    return get_switch, get_switch_timing


def build_pss_object_mask(db, tile_type_name):
    """
    Looks for objects present in PSS* tiles of Zynq7 and masks out those
    that are purely PS related and not configued by the PL.
    """

    tile_type = db.get_tile_type(tile_type_name)
    sites = tile_type.get_sites()

    masked_wires = []
    masked_pips = []

    # Get all IOPADS for MIO and DDR signals
    iopad_sites = [s for s in sites if s.type == "IOPAD"]
    for site in iopad_sites:

        # Get pins/wires
        site_pins = [p for p in site.site_pins if p.name == "IO"]
        for site_pin in site_pins:

            # Mask the wire
            masked_wires.append(site_pin.wire)

            # Find a PIP(s) for this wire, mask them as well as wires on
            # their other sides.
            for p in tile_type.get_pips():
                if p.net_from == site_pin.wire:
                    masked_pips.append(p.name)
                    masked_wires.append(p.net_to)
                if p.net_to == site_pin.wire:
                    masked_pips.append(p.name)
                    masked_wires.append(p.net_from)

    # Masked sites names
    masked_sites = [(s.prefix, s.name) for s in iopad_sites]

    return masked_sites, masked_wires, masked_pips


def import_tile_type(
        db, write_cur, tile_types, site_types, tile_type_name, get_switch
):
    assert tile_type_name not in tile_types
    tile_type = db.get_tile_type(tile_type_name)

    # For Zynq7 PSS* tiles build a list of sites, wires and PIPs to ignore
    if tile_type_name.startswith("PSS"):
        masked_sites, masked_wires, masked_pips = build_pss_object_mask(
            db, tile_type_name
        )

    else:
        masked_sites = []
        masked_wires = []
        masked_pips = []

    write_cur.execute(
        "INSERT INTO tile_type(name) VALUES (?)", (tile_type_name, )
    )
    tile_types[tile_type_name] = write_cur.lastrowid

    wires = {}
    for wire, wire_rc_element in tile_type.get_wires().items():
        if wire in masked_wires:
            continue

        capacitance = 0.0
        resistance = 0.0

        if wire_rc_element is not None:
            # microFarads -> Farads
            capacitance = wire_rc_element.capacitance / 1e6

            # milliOhms -> Ohms
            resistance = wire_rc_element.resistance / 1e3

        write_cur.execute(
            """
INSERT INTO wire_in_tile(name, phy_tile_type_pkey, tile_type_pkey, capacitance, resistance)
VALUES
  (?, ?, ?, ?, ?)""", (
                wire, tile_types[tile_type_name], tile_types[tile_type_name],
                capacitance, resistance
            )
        )
        wires[wire] = write_cur.lastrowid

    for pip in tile_type.get_pips():
        if pip.name in masked_pips:
            continue

        switch_pkey = get_switch(pip, pip.timing)
        backward_switch_pkey = get_switch(pip, pip.backward_timing)

        write_cur.execute(
            """
INSERT INTO pip_in_tile(
  name, tile_type_pkey, src_wire_in_tile_pkey,
  dest_wire_in_tile_pkey, can_invert, is_directional, is_pseudo,
  is_pass_transistor, switch_pkey, backward_switch_pkey
)
VALUES
  (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", (
                pip.name, tile_types[tile_type_name], wires[pip.net_from],
                wires[pip.net_to
                      ], pip.can_invert, pip.is_directional, pip.is_pseudo,
                pip.is_pass_transistor, switch_pkey, backward_switch_pkey
            )
        )
        pip_pkey = write_cur.lastrowid

        write_cur.execute(
            """
INSERT INTO undirected_pips(
    wire_in_tile_pkey, pip_in_tile_pkey, other_wire_in_tile_pkey)
VALUES
    (?, ?, ?), (?, ?, ?);""", (
                wires[pip.net_from],
                pip_pkey,
                wires[pip.net_to],
                wires[pip.net_to],
                pip_pkey,
                wires[pip.net_from],
            )
        )

    for site in tile_type.get_sites():
        if (site.prefix, site.name) in masked_sites:
            continue

        if site.type not in site_types:
            import_site_type(db, write_cur, site_types, site.type)


def add_wire_to_site_relation(
        db, write_cur, tile_types, site_types, tile_type_name,
        get_switch_timing
):
    tile_type = db.get_tile_type(tile_type_name)
    for site in tile_type.get_sites():

        if site.type not in site_types:
            continue

        write_cur.execute(
            """
INSERT INTO site(name, x_coord, y_coord, site_type_pkey, tile_type_pkey)
VALUES
  (?, ?, ?, ?, ?)""", (
                site.name, site.x, site.y, site_types[site.type],
                tile_types[tile_type_name]
            )
        )

        site_pkey = write_cur.lastrowid

        for site_pin in site.site_pins:
            write_cur.execute(
                """
SELECT
  pkey
FROM
  site_pin
WHERE
  name = ?
  AND site_type_pkey = ?""", (site_pin.name, site_types[site.type])
            )
            result = write_cur.fetchone()
            site_pin_pkey = result[0]

            intrinsic_delay = 0
            drive_resistance = 0
            capacitance = 0

            if site_pin.timing is not None:
                # Use the largest intristic delay for now.
                # This conservative on slack timing, but not on hold timing.
                #
                # nanosecond -> seconds
                intrinsic_delay = site_pin.timing.delays[PvtCorner.SLOW
                                                         ].max / 1e9

                if isinstance(site_pin.timing, prjxray.tile.OutPinTiming):
                    # milliOhms -> Ohms
                    drive_resistance = site_pin.timing.drive_resistance / 1e3
                elif isinstance(site_pin.timing, prjxray.tile.InPinTiming):
                    # microFarads -> Farads
                    capacitance = site_pin.timing.capacitance / 1e6
                else:
                    assert False, site_pin
            else:
                # Use min value instead of 0 to prevent
                # VPR from freaking out over a zero net delay.
                #
                # Note this is the single precision float minimum, because VPR
                # uses single precision, not double precision.
                intrinsic_delay = SINGLE_PRECISION_FLOAT_MIN

            site_pin_switch_pkey = get_switch_timing(
                is_pass_transistor=False,
                delay=intrinsic_delay,
                internal_capacitance=capacitance,
                drive_resistance=drive_resistance,
            )

            write_cur.execute(
                """
UPDATE
  wire_in_tile
SET
  site_pkey = ?,
  site_pin_pkey = ?,
  site_pin_switch_pkey = ?
WHERE
  name = ?
  and tile_type_pkey = ?;""", (
                    site_pkey, site_pin_pkey, site_pin_switch_pkey,
                    site_pin.wire, tile_types[tile_type_name]
                )
            )


def build_tile_type_indicies(write_cur):
    write_cur.execute(
        "CREATE INDEX site_pin_index ON site_pin(name, site_type_pkey);"
    )
    write_cur.execute(
        "CREATE INDEX wire_name_index ON wire_in_tile(name, tile_type_pkey);"
    )
    write_cur.execute(
        "CREATE INDEX wire_tile_site_index ON wire_in_tile(tile_type_pkey, site_pkey);"
    )
    write_cur.execute(
        "CREATE INDEX wire_site_pin_index ON wire_in_tile(site_pin_pkey);"
    )
    write_cur.execute(
        "CREATE INDEX tile_type_index ON phy_tile(tile_type_pkey);"
    )
    write_cur.execute(
        "CREATE INDEX pip_tile_type_index ON pip_in_tile(tile_type_pkey);"
    )
    write_cur.execute(
        "CREATE INDEX src_pip_index ON pip_in_tile(src_wire_in_tile_pkey);"
    )
    write_cur.execute(
        "CREATE INDEX dest_pip_index ON pip_in_tile(dest_wire_in_tile_pkey);"
    )
    write_cur.execute(
        """CREATE INDEX undirected_pip_index ON
undirected_pips(wire_in_tile_pkey, other_wire_in_tile_pkey);"""
    )


def build_other_indicies(write_cur):
    write_cur.execute("CREATE INDEX phy_tile_name_index ON phy_tile(name);")
    write_cur.execute(
        "CREATE INDEX phy_tile_location_index ON phy_tile(grid_x, grid_y);"
    )
    write_cur.execute(
        "CREATE INDEX site_instance_index on site_instance(name);"
    )


def import_phy_grid(db, grid, conn, get_switch, get_switch_timing):
    write_cur = conn.cursor()

    tile_types = {}
    site_types = {}

    for tile in grid.tiles():
        gridinfo = grid.gridinfo_at_tilename(tile)

        if gridinfo.tile_type not in tile_types:
            if gridinfo.tile_type in tile_types:
                continue

            import_tile_type(
                db, write_cur, tile_types, site_types, gridinfo.tile_type,
                get_switch
            )

    write_cur.connection.commit()

    build_tile_type_indicies(write_cur)
    write_cur.connection.commit()

    for tile_type in tile_types:
        add_wire_to_site_relation(
            db, write_cur, tile_types, site_types, tile_type, get_switch_timing
        )

    clock_regions = {}

    for tile in grid.tiles():
        gridinfo = grid.gridinfo_at_tilename(tile)

        clock_region_pkey = None
        if gridinfo.clock_region is not None:
            if gridinfo.clock_region.name not in clock_regions:
                write_cur.execute(
                    """
INSERT INTO clock_region(name, x_coord, y_coord)
VALUES (?, ?, ?)""", (
                        gridinfo.clock_region.name,
                        gridinfo.clock_region.x,
                        gridinfo.clock_region.y,
                    )
                )
                clock_regions[gridinfo.clock_region.name] = write_cur.lastrowid

            clock_region_pkey = clock_regions[gridinfo.clock_region.name]

        loc = grid.loc_of_tilename(tile)
        # tile: pkey name tile_type_pkey grid_x grid_y
        write_cur.execute(
            """
INSERT INTO phy_tile(name, tile_type_pkey, grid_x, grid_y, clock_region_pkey)
VALUES
  (?, ?, ?, ?, ?)""", (
                tile,
                tile_types[gridinfo.tile_type],
                loc.grid_x,
                loc.grid_y,
                clock_region_pkey,
            )
        )
        phy_tile_pkey = write_cur.lastrowid

        tile_type = db.get_tile_type(gridinfo.tile_type)
        for site, instance_site in zip(tile_type.sites,
                                       tile_type.get_instance_sites(gridinfo)):
            write_cur.execute(
                """
INSERT INTO site_instance(name, x_coord, y_coord, site_pkey, phy_tile_pkey)
SELECT ?, ?, ?, site.pkey, ?
FROM site
WHERE
    site.name = ?
AND
    site.x_coord = ?
AND
    site.y_coord = ?
AND
    site.site_type_pkey = (SELECT pkey FROM site_type WHERE name = ?)
AND
    tile_type_pkey = ?;
                """, (
                    instance_site.name,
                    instance_site.x,
                    instance_site.y,
                    phy_tile_pkey,
                    site.name,
                    site.x,
                    site.y,
                    site.type,
                    tile_types[gridinfo.tile_type],
                )
            )

            site_instance_pkey = write_cur.lastrowid

            write_cur.execute(
                "UPDATE site_instance SET prohibited = ? WHERE pkey = ?", (
                    instance_site.name in gridinfo.prohibited_sites,
                    site_instance_pkey,
                )
            )

    build_other_indicies(write_cur)
    write_cur.connection.commit()


def import_nodes(db, grid, conn):
    # Some nodes are just 1 wire, so start by enumerating all wires.

    cur = conn.cursor()
    write_cur = conn.cursor()
    write_cur.execute("""BEGIN EXCLUSIVE TRANSACTION;""")

    tile_wire_map = {}
    wires = {}
    for tile in progressbar_utils.progressbar(grid.tiles()):
        gridinfo = grid.gridinfo_at_tilename(tile)
        tile_type = db.get_tile_type(gridinfo.tile_type)

        cur.execute(
            """SELECT pkey, tile_type_pkey FROM phy_tile WHERE name = ?;""",
            (tile, )
        )
        phy_tile_pkey, tile_type_pkey = cur.fetchone()

        for wire in tile_type.get_wires():
            # pkey node_pkey tile_pkey wire_in_tile_pkey
            cur.execute(
                """
SELECT pkey FROM wire_in_tile WHERE name = ? and tile_type_pkey = ?;""",
                (wire, tile_type_pkey)
            )

            wire_in_tile_pkey = cur.fetchone()
            if wire_in_tile_pkey is None:
                continue
            wire_in_tile_pkey = wire_in_tile_pkey[0]

            write_cur.execute(
                """
INSERT INTO wire(phy_tile_pkey, wire_in_tile_pkey)
VALUES
  (?, ?);""", (phy_tile_pkey, wire_in_tile_pkey)
            )

            assert (tile, wire) not in tile_wire_map
            wire_pkey = write_cur.lastrowid
            tile_wire_map[(tile, wire)] = wire_pkey
            wires[wire_pkey] = None

    write_cur.execute("""COMMIT TRANSACTION;""")

    connections = db.connections()

    for connection in progressbar_utils.progressbar(
            connections.get_connections()):
        a_pkey = tile_wire_map[
            (connection.wire_a.tile, connection.wire_a.wire)]
        b_pkey = tile_wire_map[
            (connection.wire_b.tile, connection.wire_b.wire)]

        a_node = wires[a_pkey]
        b_node = wires[b_pkey]

        if a_node is None:
            a_node = set((a_pkey, ))

        if b_node is None:
            b_node = set((b_pkey, ))

        if a_node is not b_node:
            a_node |= b_node

            for wire in a_node:
                wires[wire] = a_node

    nodes = {}
    for wire_pkey, node in wires.items():
        if node is None:
            node = set((wire_pkey, ))

        assert wire_pkey in node

        nodes[id(node)] = node

    wires_assigned = set()
    for node in progressbar_utils.progressbar(nodes.values()):
        write_cur.execute("""INSERT INTO node(number_pips) VALUES (0);""")
        node_pkey = write_cur.lastrowid

        for wire_pkey in node:
            wires_assigned.add(wire_pkey)
            write_cur.execute(
                """
            UPDATE wire
                SET node_pkey = ?
                WHERE pkey = ?
            ;""", (node_pkey, wire_pkey)
            )

    assert len(set(wires.keys()) ^ wires_assigned) == 0

    del tile_wire_map
    del nodes
    del wires

    write_cur.execute(
        "CREATE INDEX wire_in_tile_index ON wire(wire_in_tile_pkey);"
    )
    write_cur.execute(
        "CREATE INDEX wire_index ON wire(phy_tile_pkey, wire_in_tile_pkey);"
    )
    write_cur.execute("CREATE INDEX wire_node_index ON wire(node_pkey);")

    write_cur.connection.commit()


def count_sites_and_pips_on_nodes(conn):
    cur = conn.cursor()

    print("{}: Counting sites on nodes".format(datetime.datetime.now()))
    cur.execute(
        """
WITH node_sites(node_pkey, number_site_pins) AS (
  SELECT
    wire.node_pkey,
    count(wire_in_tile.site_pin_pkey)
  FROM
    wire_in_tile
    INNER JOIN wire ON wire.wire_in_tile_pkey = wire_in_tile.pkey
  WHERE
    wire_in_tile.site_pin_pkey IS NOT NULL
  GROUP BY
    wire.node_pkey
)
SELECT
  max(node_sites.number_site_pins)
FROM
  node_sites;
"""
    )

    # Nodes are only expected to have 1 site
    assert cur.fetchone()[0] == 1

    print("{}: Assigning site wires for nodes".format(datetime.datetime.now()))
    cur.execute(
        """
WITH site_wires(wire_pkey, node_pkey) AS (
  SELECT
    wire.pkey,
    wire.node_pkey
  FROM
    wire_in_tile
    INNER JOIN wire ON wire.wire_in_tile_pkey = wire_in_tile.pkey
  WHERE
    wire_in_tile.site_pin_pkey IS NOT NULL
)
UPDATE
  node
SET
  site_wire_pkey = (
    SELECT
      site_wires.wire_pkey
    FROM
      site_wires
    WHERE
      site_wires.node_pkey = node.pkey
  );
      """
    )

    print("{}: Counting pips on nodes".format(datetime.datetime.now()))
    cur.execute(
        """
    CREATE TABLE node_pip_count(
      node_pkey INT,
      number_pips INT,
      FOREIGN KEY(node_pkey) REFERENCES node(pkey)
    );"""
    )
    cur.execute(
        """
INSERT INTO node_pip_count(node_pkey, number_pips)
SELECT
  wire.node_pkey,
  count(pip_in_tile.pkey)
FROM
  pip_in_tile
  INNER JOIN wire
WHERE
  pip_in_tile.is_pseudo = 0 AND (
  pip_in_tile.src_wire_in_tile_pkey = wire.wire_in_tile_pkey
  OR pip_in_tile.dest_wire_in_tile_pkey = wire.wire_in_tile_pkey)
GROUP BY
  wire.node_pkey;"""
    )
    cur.execute("CREATE INDEX pip_count_index ON node_pip_count(node_pkey);")

    print("{}: Inserting pip counts".format(datetime.datetime.now()))
    cur.execute(
        """
UPDATE
  node
SET
  number_pips = (
    SELECT
      node_pip_count.number_pips
    FROM
      node_pip_count
    WHERE
      node_pip_count.node_pkey = node.pkey
  )
WHERE
  pkey IN (
    SELECT
      node_pkey
    FROM
      node_pip_count
  );"""
    )

    cur.execute("""DROP TABLE node_pip_count;""")

    cur.connection.commit()


def check_edge_with_mux_timing(
        conn, get_switch_timing, src_wire_pkey, dest_wire_pkey, pip_pkey
):
    """ Check if edge with mux timing can be "lumped" into the switch.

    Returns
    -------
    switch_pkey : int
        Switch primary key to model EDGE_WITH_MUX connection.

    """

    cur = conn.cursor()

    cur.execute(
        """
SELECT site_pin_switch_pkey, resistance, capacitance FROM wire_in_tile WHERE pkey = (
    SELECT wire_in_tile_pkey FROM wire WHERE pkey = ?
    )""", (src_wire_pkey, )
    )

    src_site_pin_switch_pkey, src_wire_resistance, src_wire_capacitance = cur.fetchone(
    )

    assert src_wire_resistance == 0, src_wire_pkey

    cur.execute(
        """
SELECT intrinsic_delay, drive_resistance FROM switch WHERE pkey = ?
        """, (src_site_pin_switch_pkey, )
    )
    src_site_pin_intrinsic_delay, src_site_pin_drive_resistance = cur.fetchone(
    )

    cur.execute(
        """
SELECT site_pin_switch_pkey, resistance, capacitance FROM wire_in_tile WHERE pkey = (
    SELECT wire_in_tile_pkey FROM wire WHERE pkey = ?
    )""", (dest_wire_pkey, )
    )

    dest_site_pin_switch_pkey, dest_wire_resistance, dest_wire_capacitance = cur.fetchone(
    )

    assert dest_wire_resistance == 0, dest_wire_pkey

    cur.execute(
        """
SELECT intrinsic_delay, internal_capacitance FROM switch WHERE pkey = ?
        """, (dest_site_pin_switch_pkey, )
    )
    dest_site_pin_intrinsic_delay, dest_site_pin_capacitance = cur.fetchone()

    cur.execute(
        """
SELECT name, switch_pkey FROM pip_in_tile WHERE pkey = ?""", (pip_pkey, )
    )
    pip_name, switch_pkey = cur.fetchone()

    cur.execute(
        """
SELECT
    name, intrinsic_delay, internal_capacitance, drive_resistance, switch_type
FROM switch WHERE pkey = ?
        """, (switch_pkey, )
    )
    (
        switch_name, switch_intrinsic_delay, switch_internal_capacitance,
        switch_drive_resistance, switch_type
    ) = cur.fetchone()

    assert switch_type in ["mux", "pass_gate"], (switch_pkey, switch_type)

    zero_delay_to_switch = src_site_pin_drive_resistance == 0 or (
        switch_internal_capacitance == 0 and src_wire_capacitance == 0
    )
    zero_delay_from_switch = switch_drive_resistance == 0 or (
        dest_wire_capacitance == 0 and dest_site_pin_capacitance == 0
    )

    if zero_delay_to_switch and zero_delay_from_switch and \
            src_site_pin_intrinsic_delay == 0 and \
            dest_site_pin_intrinsic_delay == 0:
        return get_switch_timing(
            is_pass_transistor=False,
            delay=switch_intrinsic_delay,
            internal_capacitance=0,
            drive_resistance=0,
        )

    if switch_type == "mux":
        switch_delay = src_site_pin_intrinsic_delay
        switch_delay += src_site_pin_drive_resistance * (
            switch_internal_capacitance + src_wire_capacitance
        )
        switch_delay += switch_intrinsic_delay
        switch_delay += switch_drive_resistance * (
            dest_wire_capacitance + dest_site_pin_capacitance
        )
        switch_delay += dest_site_pin_intrinsic_delay
    else:
        assert switch_type == "pass_gate"
        assert switch_intrinsic_delay == 0
        assert switch_drive_resistance == 0

        switch_delay = src_site_pin_intrinsic_delay
        switch_delay += src_site_pin_drive_resistance * (
            src_wire_capacitance + switch_internal_capacitance +
            dest_wire_capacitance + dest_site_pin_capacitance
        )
        switch_delay += dest_site_pin_intrinsic_delay

    return get_switch_timing(
        is_pass_transistor=False,
        delay=switch_delay,
        internal_capacitance=0,
        drive_resistance=0
    )


def classify_nodes(conn, get_switch_timing):
    write_cur = conn.cursor()

    # Nodes are NULL if they they only have either a site pin or 1 pip, but
    # nothing else.
    write_cur.execute(
        """
UPDATE node SET classification = ?
    WHERE (node.site_wire_pkey IS NULL AND node.number_pips <= 1) OR
          (node.site_wire_pkey IS NOT NULL AND node.number_pips == 0)
    ;""", (NodeClassification.NULL.value, )
    )
    write_cur.execute(
        """
UPDATE node SET classification = ?
    WHERE node.number_pips > 1 and node.site_wire_pkey IS NULL;""",
        (NodeClassification.CHANNEL.value, )
    )
    write_cur.execute(
        """
UPDATE node SET classification = ?
    WHERE node.number_pips > 1 and node.site_wire_pkey IS NOT NULL;""",
        (NodeClassification.EDGES_TO_CHANNEL.value, )
    )

    null_nodes = []
    edges_to_channel = []
    edge_with_mux = []

    cur = conn.cursor()
    cur.execute(
        """
SELECT
  count(pkey)
FROM
  node
WHERE
  number_pips == 1
  AND site_wire_pkey IS NOT NULL;"""
    )
    num_nodes = cur.fetchone()[0]
    with progressbar_utils.ProgressBar(max_value=num_nodes) as bar:
        bar.update(0)
        for idx, (node, site_wire_pkey) in enumerate(cur.execute("""
SELECT
  pkey,
  site_wire_pkey
FROM
  node
WHERE
  number_pips == 1
  AND site_wire_pkey IS NOT NULL;""")):
            bar.update(idx)

            write_cur.execute(
                """
WITH wire_in_node(
  wire_pkey, phy_tile_pkey, wire_in_tile_pkey
) AS (
  SELECT
    wire.pkey,
    wire.phy_tile_pkey,
    wire.wire_in_tile_pkey
  FROM
    wire
  WHERE
    wire.node_pkey = ?
)
SELECT
  pip_in_tile.pkey,
  pip_in_tile.src_wire_in_tile_pkey,
  pip_in_tile.dest_wire_in_tile_pkey,
  wire_in_node.wire_pkey,
  wire_in_node.wire_in_tile_pkey,
  wire_in_node.phy_tile_pkey
FROM
  wire_in_node
  INNER JOIN pip_in_tile
WHERE
  pip_in_tile.is_pseudo = 0 AND (
  pip_in_tile.src_wire_in_tile_pkey = wire_in_node.wire_in_tile_pkey
  OR pip_in_tile.dest_wire_in_tile_pkey = wire_in_node.wire_in_tile_pkey)
LIMIT
  1;
""", (node, )
            )

            (
                pip_pkey, src_wire_in_tile_pkey, dest_wire_in_tile_pkey,
                wire_in_node_pkey, wire_in_tile_pkey, phy_tile_pkey
            ) = write_cur.fetchone()
            assert write_cur.fetchone() is None, node

            assert (
                wire_in_tile_pkey == src_wire_in_tile_pkey
                or wire_in_tile_pkey == dest_wire_in_tile_pkey
            ), (wire_in_tile_pkey, pip_pkey)

            if src_wire_in_tile_pkey == wire_in_tile_pkey:
                other_wire = dest_wire_in_tile_pkey
            else:
                other_wire = src_wire_in_tile_pkey

            write_cur.execute(
                """
            SELECT node_pkey FROM wire WHERE
                wire_in_tile_pkey = ? AND
                phy_tile_pkey = ?;
                """, (other_wire, phy_tile_pkey)
            )

            (other_node_pkey, ) = write_cur.fetchone()
            assert write_cur.fetchone() is None
            assert other_node_pkey is not None, (other_wire, phy_tile_pkey)

            write_cur.execute(
                """
            SELECT site_wire_pkey, number_pips
                FROM node WHERE pkey = ?;
                """, (other_node_pkey, )
            )

            result = write_cur.fetchone()
            assert result is not None, other_node_pkey
            other_site_wire_pkey, other_number_pips = result
            assert write_cur.fetchone() is None

            force_direct = False

            write_cur.execute(
                """
            SELECT name
                FROM pip_in_tile WHERE pkey = ?;
                """, (pip_pkey, )
            )
            pip_name = write_cur.fetchone()[0]

            # A solution for:
            # https://github.com/SymbiFlow/f4pga-arch-defs/issues/1033
            if "PADOUT0" in pip_name and "DIFFI_IN1" in pip_name:
                force_direct = True
            if "PADOUT1" in pip_name and "DIFFI_IN0" in pip_name:
                force_direct = True

            if other_site_wire_pkey is not None and (other_number_pips == 1
                                                     or force_direct):
                if src_wire_in_tile_pkey == wire_in_tile_pkey:
                    src_wire_pkey = site_wire_pkey
                    dest_wire_pkey = other_site_wire_pkey
                else:
                    src_wire_pkey = other_site_wire_pkey
                    dest_wire_pkey = site_wire_pkey

                edge_with_mux.append(
                    (
                        (node, other_node_pkey), src_wire_pkey, dest_wire_pkey,
                        pip_pkey
                    )
                )
            elif other_site_wire_pkey is None and other_number_pips == 1:
                null_nodes.append(node)
                null_nodes.append(other_node_pkey)
                pass
            else:
                edges_to_channel.append(node)

    for nodes, src_wire_pkey, dest_wire_pkey, pip_pkey in progressbar_utils.progressbar(
            edge_with_mux):
        assert len(nodes) == 2

        switch_pkey = check_edge_with_mux_timing(
            conn, get_switch_timing, src_wire_pkey, dest_wire_pkey, pip_pkey
        )
        write_cur.execute(
            """
        UPDATE node SET classification = ?
            WHERE pkey IN (?, ?);""",
            (NodeClassification.EDGE_WITH_MUX.value, nodes[0], nodes[1])
        )

        write_cur.execute(
            """
INSERT INTO edge_with_mux(src_wire_pkey, dest_wire_pkey, pip_in_tile_pkey, switch_pkey)
VALUES
  (?, ?, ?, ?);""", (src_wire_pkey, dest_wire_pkey, pip_pkey, switch_pkey)
        )

    for node in progressbar_utils.progressbar(edges_to_channel):
        write_cur.execute(
            """
        UPDATE node SET classification = ?
            WHERE pkey = ?;""", (
                NodeClassification.EDGES_TO_CHANNEL.value,
                node,
            )
        )

    for null_node in progressbar_utils.progressbar(null_nodes):
        write_cur.execute(
            """
        UPDATE node SET classification = ?
            WHERE pkey = ?;""", (
                NodeClassification.NULL.value,
                null_node,
            )
        )

    write_cur.execute("CREATE INDEX node_type_index ON node(classification);")
    write_cur.execute(
        """
    CREATE INDEX edge_with_mux_index ON edge_with_mux(
        src_wire_pkey,
        dest_wire_pkey,
        pip_in_tile_pkey,
        switch_pkey);"""
    )
    write_cur.connection.commit()


def get_node_rc(conn, node_pkey):
    """ Returns capacitance and resistance for given node.

    Returns
    -------
    capacitance : float
        Node capacitance (Farads)
    resistance : float
        Node resistance (Ohms)

    """
    capacitance = 0
    resistance = 0

    cur = conn.cursor()
    for wire_cap, wire_res in cur.execute("""
SELECT capacitance, resistance FROM wire_in_tile WHERE pkey IN (
    SELECT wire_in_tile_pkey FROM wire WHERE node_pkey = ?
    );""", (node_pkey, )):
        capacitance += wire_cap
        resistance += wire_res

    return capacitance, resistance


def get_segment_for_node(cur, segments, node_pkey):
    """ Attempt to determine the segment for the given node.

    Parameters
    ----------
    conn : sqlite3.Connection
        Connection to channels.db
    segments : SegmentWireMap
        Object for determined segment based on wire names.
    node_pkey : int
        Node to determine segment of.  Is primary key into node table.

    Returns
    -------
    segment_pkey : int
        Primary key to segment table of segment for this node.

    """

    cur.execute(
        """
SELECT name FROM wire_in_tile WHERE pkey IN (
    SELECT wire_in_tile_pkey FROM wire WHERE node_pkey = ?
);""", (node_pkey, )
    )

    segment_name = segments.get_segment_for_wires(
        wire for (wire, ) in cur.fetchall()
    )

    cur.execute(
        """
SELECT pkey FROM segment WHERE name = ?
    """, (segment_name, )
    )

    return cur.fetchone()[0]


def insert_tracks(conn, segments, tracks_to_insert):
    write_cur = conn.cursor()
    write_cur.execute('SELECT pkey FROM switch WHERE name = "short";')
    short_pkey = write_cur.fetchone()[0]

    track_graph_nodes = {}
    track_pkeys = []
    for node, tracks_list, track_conn, tracks_model, seg_pkey in progressbar_utils.progressbar(
            tracks_to_insert):
        write_cur.execute(
            """INSERT INTO track(segment_pkey) VALUES (?)""", (seg_pkey, )
        )
        track_pkey = write_cur.lastrowid
        track_pkeys.append(track_pkey)

        write_cur.execute(
            """UPDATE node SET track_pkey = ? WHERE pkey = ?""",
            (track_pkey, node)
        )

        track_graph_node_pkey = []
        for idx, track in enumerate(tracks_list):
            if track.direction == 'X':
                node_type = graph2.NodeType.CHANX
            elif track.direction == 'Y':
                node_type = graph2.NodeType.CHANY
            else:
                assert False, track.direction

            if idx == 0:
                capacitance, resistance = get_node_rc(conn, node)
            else:
                capacitance = 0
                resistance = 0

            write_cur.execute(
                """
INSERT INTO graph_node(
  graph_node_type, track_pkey, node_pkey,
  x_low, x_high, y_low, y_high, capacity, capacitance, resistance
)
VALUES
  (?, ?, ?, ?, ?, ?, ?, 1, ?, ?)""", (
                    node_type.value, track_pkey, node, track.x_low,
                    track.x_high, track.y_low, track.y_high, capacitance,
                    resistance
                )
            )
            track_graph_node_pkey.append(write_cur.lastrowid)

        track_graph_nodes[node] = track_graph_node_pkey

        for connection in track_conn:
            write_cur.execute(
                """
INSERT INTO graph_edge(
  src_graph_node_pkey, dest_graph_node_pkey,
  switch_pkey, track_pkey
)
VALUES
  (?, ?, ?, ?),
  (?, ?, ?, ?)""", (
                    track_graph_node_pkey[connection[0]],
                    track_graph_node_pkey[connection[1]],
                    short_pkey,
                    track_pkey,
                    track_graph_node_pkey[connection[1]],
                    track_graph_node_pkey[connection[0]],
                    short_pkey,
                    track_pkey,
                )
            )

    conn.commit()

    wire_to_graph = {}
    for node, tracks_list, track_conn, tracks_model, _ in progressbar_utils.progressbar(
            tracks_to_insert):
        track_graph_node_pkey = track_graph_nodes[node]

        write_cur.execute(
            """
WITH wires_from_node(wire_pkey, tile_pkey) AS (
  SELECT
    pkey,
    tile_pkey
  FROM
    wire
  WHERE
    node_pkey = ?
)
SELECT
  wires_from_node.wire_pkey,
  tile.grid_x,
  tile.grid_y
FROM
  tile
  INNER JOIN wires_from_node ON tile.pkey = wires_from_node.tile_pkey;
  """, (node, )
        )

        wires = write_cur.fetchall()

        for wire_pkey, grid_x, grid_y in wires:
            connections = list(
                tracks_model.get_tracks_for_wire_at_coord((grid_x,
                                                           grid_y)).values()
            )
            assert len(connections) > 0, (
                connections, wire_pkey, track_pkey, grid_x, grid_y, node
            )
            graph_node_pkey = track_graph_node_pkey[connections[0]]

            wire_to_graph[wire_pkey] = graph_node_pkey

    for wire_pkey, graph_node_pkey in progressbar_utils.progressbar(
            wire_to_graph.items()):
        write_cur.execute(
            """
        UPDATE wire SET graph_node_pkey = ?
            WHERE pkey = ?""", (graph_node_pkey, wire_pkey)
        )

    conn.commit()

    write_cur.execute(
        """CREATE INDEX graph_node_nodes ON graph_node(node_pkey);"""
    )
    write_cur.execute(
        """CREATE INDEX graph_node_tracks ON graph_node(track_pkey);"""
    )
    write_cur.execute(
        """CREATE INDEX graph_edge_tracks ON graph_edge(track_pkey);"""
    )

    conn.commit()
    return track_pkeys


def create_track(node, unique_pos):
    xs, ys = points.decompose_points_into_tracks(unique_pos)
    tracks_list, track_connections = tracks.make_tracks(xs, ys, unique_pos)
    tracks_model = tracks.Tracks(tracks_list, track_connections)

    return [node, tracks_list, track_connections, tracks_model]


def form_tracks(conn, segments):
    cur = conn.cursor()
    cur2 = conn.cursor()

    cur.execute(
        'SELECT count(pkey) FROM node WHERE classification == ?;',
        (NodeClassification.CHANNEL.value, )
    )
    num_nodes = cur.fetchone()[0]

    tracks_to_insert = []
    with progressbar_utils.ProgressBar(max_value=num_nodes) as bar:
        bar.update(0)
        for idx, (node_pkey, ) in enumerate(cur.execute("""
SELECT pkey FROM node WHERE classification == ?;
""", (NodeClassification.CHANNEL.value, ))):
            bar.update(idx)

            unique_pos = set()

            # Get coordinates for all wires in this node.
            for grid_x, grid_y in cur2.execute("""
SELECT DISTINCT grid_x, grid_y FROM tile WHERE pkey IN (
    SELECT tile_pkey FROM wire WHERE node_pkey = ? AND tile_pkey IS NOT NULL
    )""", (node_pkey, )):
                unique_pos.add((grid_x, grid_y))

            # Find the VPR grid locations that this channel connects to.
            #
            # Algorithm:
            #  1. Identify all pips that connect to or from this node
            #  2. Traverse each pip, and determine if the connected node is a
            #     EDGES_TO_CHANNEL.  NULL nodes are uninteresting, and CHANNEL
            #     nodes are already covered in the earlier loop getting
            #     locations of the
            #     discarded.
            #  3a. For CHANNEL to CHANNEL connections, use the pip location.
            #  3b. For CHANNEL to EDGES_TO_CHANNEL (e.g. site pin connections)
            #      use location of site in VPR grid.

            # 3a loop
            for grid_x, grid_y in cur2.execute("""
-- Get wires from this node
WITH wires_from_node(wire_in_tile_pkey, phy_tile_pkey) AS (
  SELECT
    wire_in_tile_pkey,
    phy_tile_pkey
  FROM
    wire
  WHERE
    node_pkey = ? AND tile_pkey IS NOT NULL
),
  other_wires(phy_tile_pkey, wire_in_tile_pkey) AS (
    SELECT
        wires_from_node.phy_tile_pkey,
        undirected_pips.other_wire_in_tile_pkey
    FROM undirected_pips
    INNER JOIN wires_from_node ON
        undirected_pips.wire_in_tile_pkey = wires_from_node.wire_in_tile_pkey)
SELECT tile.grid_x, tile.grid_y
FROM tile
WHERE pkey IN (
    SELECT wire.tile_pkey FROM wire
    INNER JOIN other_wires ON
        wire.wire_in_tile_pkey = other_wires.wire_in_tile_pkey
    AND
        wire.phy_tile_pkey = other_wires.phy_tile_pkey
        );""", (node_pkey, )):
                unique_pos.add((grid_x, grid_y))

            # 3b loop
            for grid_x, grid_y in cur2.execute("""
-- Get wires from this node
WITH wires_from_node(wire_in_tile_pkey, phy_tile_pkey) AS (
  SELECT
    wire_in_tile_pkey,
    phy_tile_pkey
  FROM
    wire
  WHERE
    node_pkey = ? AND tile_pkey IS NOT NULL
),
  other_wires(phy_tile_pkey, wire_in_tile_pkey) AS (
    SELECT
        wires_from_node.phy_tile_pkey,
        undirected_pips.other_wire_in_tile_pkey
    FROM undirected_pips
    INNER JOIN wires_from_node ON
        undirected_pips.wire_in_tile_pkey = wires_from_node.wire_in_tile_pkey),
  other_nodes(other_node_pkey) AS (
    SELECT wire.node_pkey FROM wire
    INNER JOIN other_wires ON
        wire.wire_in_tile_pkey = other_wires.wire_in_tile_pkey
    AND
        wire.phy_tile_pkey = other_wires.phy_tile_pkey),
  other_tiles(site_wire_pkey) AS (
    SELECT node.site_wire_pkey FROM node
    WHERE
        pkey IN (SELECT other_node_pkey FROM other_nodes)
    AND
        classification = ?
  )
SELECT tile.grid_x, tile.grid_y
FROM tile
WHERE pkey IN (
    SELECT DISTINCT tile_pkey
    FROM wire
    WHERE pkey IN (
        SELECT other_tiles.site_wire_pkey FROM other_tiles
        )
    );
  """, (node_pkey, NodeClassification.EDGES_TO_CHANNEL.value)):
                unique_pos.add((grid_x, grid_y))

            # Determine segment for each routing resource.
            segment_pkey = get_segment_for_node(cur2, segments, node_pkey)

            tracks_to_insert.append(
                create_track(node_pkey, unique_pos) + [segment_pkey]
            )

    # Create constant tracks
    vcc_track_to_insert, gnd_track_to_insert = create_constant_tracks(conn)

    # Assign constant networks special segments to given them dedicated
    # router lookaheads.
    cur.execute("SELECT pkey FROM segment WHERE name = ?", (VCC_NET, ))
    vcc_segment_pkey = cur.fetchone()[0]

    cur.execute("SELECT pkey FROM segment WHERE name = ?", (GND_NET, ))
    gnd_segment_pkey = cur.fetchone()[0]

    vcc_idx = len(tracks_to_insert)
    tracks_to_insert.append(vcc_track_to_insert + [vcc_segment_pkey])
    gnd_idx = len(tracks_to_insert)
    tracks_to_insert.append(gnd_track_to_insert + [gnd_segment_pkey])

    track_pkeys = insert_tracks(conn, segments, tracks_to_insert)
    vcc_track_pkey = track_pkeys[vcc_idx]
    gnd_track_pkey = track_pkeys[gnd_idx]

    write_cur = conn.cursor()
    write_cur.execute(
        """
INSERT INTO constant_sources(vcc_track_pkey, gnd_track_pkey) VALUES (?, ?)
        """, (
            vcc_track_pkey,
            gnd_track_pkey,
        )
    )

    # Create synthetic physical tile for constant network to assign a
    # canonical location too.
    #
    # This location is not important, but exists for uniformity with other
    # routing nodes.
    write_cur.execute(
        """
INSERT INTO phy_tile(name, grid_x, grid_y) VALUES (?, ?, ?)
        """, ("CONSTANT_SOURCE", 1, 1)
    )
    zero_phy_tile_pkey = write_cur.lastrowid

    write_cur.execute(
        "UPDATE track SET canon_phy_tile_pkey = ? WHERE pkey = ?", (
            zero_phy_tile_pkey,
            vcc_track_pkey,
        )
    )
    write_cur.execute(
        "UPDATE track SET canon_phy_tile_pkey = ? WHERE pkey = ?", (
            zero_phy_tile_pkey,
            gnd_track_pkey,
        )
    )

    conn.commit()

    connect_hardpins_to_constant_network(conn, vcc_track_pkey, gnd_track_pkey)


def connect_hardpins_to_constant_network(conn, vcc_track_pkey, gnd_track_pkey):
    """ Connect TIEOFF HARD1 and HARD0 pins.

    Update nodes connected to to HARD1 or HARD0 pins to point to the new
    VCC or GND track.  This should connect the pips to the constant
    network instead of the TIEOFF site.
    """

    cur = conn.cursor()
    cur.execute(
        """
SELECT pkey FROM site_type WHERE name = ?
""", ("TIEOFF", )
    )
    results = cur.fetchall()
    assert len(results) == 1, results
    tieoff_site_type_pkey = results[0][0]

    cur.execute(
        """
SELECT pkey FROM site_pin WHERE site_type_pkey = ? and name = ?
""", (tieoff_site_type_pkey, "HARD1")
    )
    vcc_site_pin_pkey = cur.fetchone()[0]
    cur.execute(
        """
SELECT pkey FROM wire_in_tile WHERE site_pin_pkey = ?
""", (vcc_site_pin_pkey, )
    )

    cur.execute(
        """
SELECT pkey FROM wire_in_tile WHERE site_pin_pkey = ?
""", (vcc_site_pin_pkey, )
    )

    write_cur = conn.cursor()
    write_cur.execute("""BEGIN EXCLUSIVE TRANSACTION;""")

    for (wire_in_tile_pkey, ) in cur:
        write_cur.execute(
            """
UPDATE node SET track_pkey = ? WHERE pkey IN (
    SELECT node_pkey FROM wire WHERE wire_in_tile_pkey = ?
)
            """, (
                vcc_track_pkey,
                wire_in_tile_pkey,
            )
        )

    cur.execute(
        """
SELECT pkey FROM site_pin WHERE site_type_pkey = ? and name = ?
""", (tieoff_site_type_pkey, "HARD0")
    )
    gnd_site_pin_pkey = cur.fetchone()[0]

    cur.execute(
        """
SELECT pkey FROM wire_in_tile WHERE site_pin_pkey = ?
""", (gnd_site_pin_pkey, )
    )
    for (wire_in_tile_pkey, ) in cur:
        write_cur.execute(
            """
UPDATE node SET track_pkey = ? WHERE pkey IN (
    SELECT node_pkey FROM wire WHERE wire_in_tile_pkey = ?
)
            """, (
                gnd_track_pkey,
                wire_in_tile_pkey,
            )
        )

    write_cur.execute("""COMMIT TRANSACTION""")


def traverse_pip(conn, wire_in_tile_pkey):
    """ Given a generic wire, find (if any) the wire on the other side of a pip.

    Returns None if no wire or pip connects to this wire.

    """
    cur = conn.cursor()

    cur.execute(
        """
SELECT src_wire_in_tile_pkey FROM pip_in_tile WHERE
    is_pseudo = 0 AND
    dest_wire_in_tile_pkey = ?
    ;""", (wire_in_tile_pkey, )
    )

    result = cur.fetchone()
    if result is not None:
        return result[0]

    cur.execute(
        """
SELECT dest_wire_in_tile_pkey FROM pip_in_tile WHERE
    is_pseudo = 0 AND
    src_wire_in_tile_pkey = ?
    ;""", (wire_in_tile_pkey, )
    )

    result = cur.fetchone()
    if result is not None:
        return result[0]

    return None


def update_wire_in_tile_types(
        cur, write_cur, empty_tile_type_pkey, wire_in_tile_pkey_to_update
):
    # Check if each wire in tile pkey can point to one logical tile type.
    wire_in_tile_pkey_to_tile_type_pkey = {}

    for tile_type_pkey, wire_in_tile_pkeys in wire_in_tile_pkey_to_update.items(
    ):
        for wire_in_tile_pkey in wire_in_tile_pkeys:
            if wire_in_tile_pkey not in wire_in_tile_pkey_to_tile_type_pkey:
                wire_in_tile_pkey_to_tile_type_pkey[wire_in_tile_pkey] = set()

            wire_in_tile_pkey_to_tile_type_pkey[wire_in_tile_pkey].add(
                tile_type_pkey
            )

    wire_in_tile_pkey_to_updates = list(
        wire_in_tile_pkey_to_tile_type_pkey.keys()
    )
    wire_in_tile_pkey_updates = []
    for wire_in_tile_pkey in wire_in_tile_pkey_to_updates:
        cur.execute(
            "SELECT phy_tile_type_pkey FROM wire_in_tile WHERE pkey = ?",
            (wire_in_tile_pkey, )
        )
        phy_tile_type_pkey = cur.fetchone()[0]
        if phy_tile_type_pkey == empty_tile_type_pkey:
            del wire_in_tile_pkey_to_tile_type_pkey[wire_in_tile_pkey]
            continue

        tile_type_pkeys = wire_in_tile_pkey_to_tile_type_pkey[wire_in_tile_pkey
                                                              ]
        assert len(tile_type_pkeys) == 1, (wire_in_tile_pkey, tile_type_pkeys)

        wire_in_tile_pkey_updates.append(
            (list(tile_type_pkeys)[0], wire_in_tile_pkey)
        )

    write_cur.executemany(
        """
    UPDATE wire_in_tile
    SET tile_type_pkey = ?
    WHERE pkey = ?;""", wire_in_tile_pkey_updates
    )


def create_vpr_grid(conn, grid_map_output):
    """ Create VPR grid from prjxray grid. """
    cur = conn.cursor()
    cur2 = conn.cursor()

    slice_types = {}

    write_cur = conn.cursor()
    write_cur.execute("""BEGIN EXCLUSIVE TRANSACTION;""")

    # Insert synthetic tile types for CLB sites and iopad sites.
    for name in [
            'SLICEL',
            'SLICEM',
            'LIOPAD_M',
            'LIOPAD_S',
            'LIOPAD_SING',
            'RIOPAD_M',
            'RIOPAD_S',
            'RIOPAD_SING',
    ]:
        write_cur.execute('INSERT INTO tile_type(name) VALUES (?);', (name, ))
        slice_types[name] = write_cur.lastrowid

    write_cur.execute("""COMMIT TRANSACTION;""")

    tiles_to_merge = {
        'LIOB33_SING': tile_splitter.grid.EAST,
        'LIOB33': tile_splitter.grid.EAST,
        'RIOB33_SING': tile_splitter.grid.WEST,
        'RIOB33': tile_splitter.grid.WEST,
    }

    tiles_to_split = {
        'LIOI3': tile_splitter.grid.NORTH,
        'LIOI3_TBYTESRC': tile_splitter.grid.NORTH,
        'LIOI3_TBYTETERM': tile_splitter.grid.NORTH,
        'LIOI3_SING': tile_splitter.grid.NORTH,
        'RIOI3': tile_splitter.grid.NORTH,
        'RIOI3_TBYTESRC': tile_splitter.grid.NORTH,
        'RIOI3_TBYTETERM': tile_splitter.grid.NORTH,
        'RIOI3_SING': tile_splitter.grid.NORTH,
    }

    liopad_ms_split = {
        1: slice_types['LIOPAD_M'],
        0: slice_types['LIOPAD_S'],
    }
    riopad_ms_split = {
        1: slice_types['RIOPAD_M'],
        0: slice_types['RIOPAD_S'],
    }

    split_styles = {
        'LIOI3': ('y_split', liopad_ms_split),
        'LIOI3_TBYTESRC': ('y_split', liopad_ms_split),
        'LIOI3_TBYTETERM': ('y_split', liopad_ms_split),
        'RIOI3': ('y_split', riopad_ms_split),
        'RIOI3_TBYTESRC': ('y_split', riopad_ms_split),
        'RIOI3_TBYTETERM': ('y_split', riopad_ms_split),
        'LIOI3_SING': ('y_split', {
            0: slice_types['LIOPAD_SING']
        }),
        'RIOI3_SING': ('y_split', {
            0: slice_types['RIOPAD_SING']
        }),
    }
    # Create initial grid using sites and locations from phy_tile's
    # Also build up tile_to_tile_type_pkeys, which is a map from original
    # tile_type_pkey, to array of split tile type pkeys, (e.g. SLICEL/SLICEM).
    tile_to_tile_type_pkeys = {}
    split_map = {}

    grid_loc_map = {}

    for phy_tile_pkey, tile_type_pkey, grid_x, grid_y in progressbar_utils.progressbar(
            cur.execute("""
        SELECT pkey, tile_type_pkey, grid_x, grid_y FROM phy_tile;
        """)):

        cur2.execute(
            "SELECT name FROM tile_type WHERE pkey = ?;", (tile_type_pkey, )
        )
        tile_type_name = cur2.fetchone()[0]

        sites = []
        site_pkeys = set()
        for (site_pkey, ) in cur2.execute("""
SELECT site_pkey FROM wire_in_tile WHERE tile_type_pkey = ? AND site_pkey IS NOT NULL;""",
                                          (tile_type_pkey, )):
            site_pkeys.add(site_pkey)

        for site_pkey in site_pkeys:
            cur2.execute(
                """
                SELECT x_coord, y_coord, site_type_pkey
                FROM site WHERE pkey = ?;""", (site_pkey, )
            )
            result = cur2.fetchone()
            assert result is not None, (tile_type_pkey, site_pkey)
            x, y, site_type_pkey = result

            cur2.execute(
                "SELECT name FROM site_type WHERE pkey = ?;",
                ((site_type_pkey, ))
            )
            site_type_name = cur2.fetchone()[0]

            sites.append(
                tile_splitter.grid.Site(
                    name=site_type_name,
                    phy_tile_pkey=phy_tile_pkey,
                    tile_type_pkey=tile_type_pkey,
                    site_type_pkey=site_type_pkey,
                    site_pkey=site_pkey,
                    x=x,
                    y=y
                )
            )

        sites = sorted(sites, key=lambda s: (s.x, s.y))

        if tile_type_name in tiles_to_split:
            tile_type_pkeys = []
            tile_split_map = {}

            if split_styles[tile_type_name][0] == 'site_as_tile':
                for idx, site in enumerate(sites):
                    tile_type_pkeys.append(slice_types[site.name])
                    tile_split_map[site.x, site.y] = idx
            elif split_styles[tile_type_name][0] == 'y_split':
                ys = set()

                for site in sites:
                    ys.add(site.y)

                ys = sorted(ys)

                tile_type_pkeys = [
                    split_styles[tile_type_name][1][y] for y in ys
                ]
                for site in sites:
                    tile_split_map[site.x, site.y] = ys.index(site.y)
            else:
                assert False, split_styles[tile_type_name]

            if tile_type_name in tile_to_tile_type_pkeys:
                assert tile_to_tile_type_pkeys[
                    tile_type_name] == tile_type_pkeys, (tile_type_name, )
                assert split_map[tile_type_name] == tile_split_map, (
                    tile_type_name,
                )
            else:
                tile_to_tile_type_pkeys[tile_type_name] = tile_type_pkeys
                split_map[tile_type_name] = tile_split_map

        grid_loc_map[(grid_x, grid_y)] = tile_splitter.grid.Tile(
            root_phy_tile_pkeys=[phy_tile_pkey],
            phy_tile_pkeys=[phy_tile_pkey],
            tile_type_pkey=tile_type_pkey,
            sites=sites
        )

    cur.execute('SELECT pkey FROM tile_type WHERE name = "NULL";')
    empty_tile_type_pkey = cur.fetchone()[0]

    tile_types = {}
    tile_type_names = {}
    for tile_type, _ in tiles_to_merge.items():
        cur.execute(
            'SELECT pkey FROM tile_type WHERE name = ?;', (tile_type, )
        )
        tile_type_pkey = cur.fetchone()
        if tile_type_pkey is not None:
            tile_type_pkey = tile_type_pkey[0]
            tile_types[tile_type] = tile_type_pkey
            tile_type_names[tile_type_pkey] = tile_type

    for tile_type, _ in tiles_to_split.items():
        cur.execute(
            'SELECT pkey FROM tile_type WHERE name = ?;', (tile_type, )
        )
        tile_type_pkey = cur.fetchone()
        if tile_type_pkey is not None:
            tile_type_pkey = tile_type_pkey[0]
            tile_types[tile_type] = tile_type_pkey
            tile_type_names[tile_type_pkey] = tile_type

    vpr_grid = tile_splitter.grid.Grid(
        grid_loc_map=grid_loc_map, empty_tile_type_pkey=empty_tile_type_pkey
    )

    # Merge tiles first, so any splits account for sites the show up after a
    # merge.
    for tile_type, merge_direction in progressbar_utils.progressbar(
            tiles_to_merge.items()):
        if tile_type in tile_types:
            vpr_grid.merge_tile_type(
                tile_type_pkey=tile_types[tile_type],
                merge_direction=merge_direction,
            )

    for tile_type, split_direction in progressbar_utils.progressbar(
            tiles_to_split.items()):
        if tile_type in tile_types:
            vpr_grid.split_tile_type(
                tile_type_pkey=tile_types[tile_type],
                tile_type_pkeys=tile_to_tile_type_pkeys[tile_type],
                split_direction=split_direction,
                split_map=split_map[tile_type],
            )

    new_grid = vpr_grid.output_grid()

    shifted_grid = {}
    for (grid_x, grid_y), tile in new_grid.items():
        # Shift grid away from 0 edges, which have limitations in VPR that
        # complicate the rrgraph import process.
        grid_x += 1
        grid_y += 1
        shifted_grid[(grid_x, grid_y)] = tile

    new_grid = shifted_grid

    write_cur.execute("""BEGIN EXCLUSIVE TRANSACTION;""")

    # Create tile rows for each tile in the VPR grid.  As provide map entries
    # to physical grid and alias map from split tile type to original tile
    # type.
    for (grid_x, grid_y), tile in new_grid.items():
        if tile.split_sites and len(tile.sites) == 1:
            write_cur.execute(
                """
SELECT pkey, parent_tile_type_pkey FROM site_as_tile WHERE tile_type_pkey = ? AND site_pkey = ?""",
                (tile.sites[0].tile_type_pkey, tile.sites[0].site_pkey)
            )
            result = write_cur.fetchone()

            if result is None:
                write_cur.execute(
                    """
INSERT INTO
    site_as_tile(parent_tile_type_pkey, tile_type_pkey, site_pkey)
VALUES
    (?, ?, ?);""", (
                        tile.tile_type_pkey, tile.sites[0].tile_type_pkey,
                        tile.sites[0].site_pkey
                    )
                )
                site_as_tile_pkey = write_cur.lastrowid
            else:
                site_as_tile_pkey, parent_tile_type_pkey = result
                assert parent_tile_type_pkey == tile.tile_type_pkey

            # Mark that this tile is split by setting the site_as_tile_pkey.
            write_cur.execute(
                """
INSERT INTO tile(phy_tile_pkey, tile_type_pkey, site_as_tile_pkey, grid_x, grid_y) VALUES (
        ?, ?, ?, ?, ?)""", (
                    tile.phy_tile_pkeys[0], tile.tile_type_pkey,
                    site_as_tile_pkey, grid_x, grid_y
                )
            )
        else:
            phy_tile_pkey = None
            if len(tile.phy_tile_pkeys) > 0:
                phy_tile_pkey = tile.phy_tile_pkeys[0]

            write_cur.execute(
                """
INSERT INTO tile(phy_tile_pkey, tile_type_pkey, grid_x, grid_y) VALUES (
        ?, ?, ?, ?)""", (phy_tile_pkey, tile.tile_type_pkey, grid_x, grid_y)
            )

        tile_pkey = write_cur.lastrowid

        # Build the phy_tile <-> tile map.
        for phy_tile_pkey in tile.phy_tile_pkeys:
            write_cur.execute(
                """
INSERT INTO tile_map(tile_pkey, phy_tile_pkey) VALUES (?, ?)
                """, (tile_pkey, phy_tile_pkey)
            )

        # First assign all wires at the root_phy_tile_pkeys to this tile_pkey.
        # This ensures all wires, (including wires without sites) have a home.

        for root_phy_tile_pkey in tile.root_phy_tile_pkeys:

            write_cur.execute(
                """
UPDATE
    wire
SET
    tile_pkey = ?
WHERE
    phy_tile_pkey = ?
    ;""", (tile_pkey, root_phy_tile_pkey)
            )

    write_cur.execute(
        "CREATE INDEX tile_location_index ON tile(grid_x, grid_y);"
    )
    write_cur.execute("CREATE INDEX tile_to_phy_map ON tile_map(tile_pkey);")
    write_cur.execute(
        "CREATE INDEX phy_to_tile_map ON tile_map(phy_tile_pkey);"
    )
    write_cur.execute("""COMMIT TRANSACTION;""")

    write_cur.execute("""BEGIN EXCLUSIVE TRANSACTION;""")

    # Track wire_in_tile_pkey's to update to new tile types.
    wire_in_tile_pkey_to_update = {}

    # At this point all wires have a tile_pkey that corrisponds to the old root
    # tile.  Wires belonging to sites need to be reassigned to their respective
    # tiles.
    for (grid_x, grid_y), tile in new_grid.items():
        cur2.execute(
            "SELECT pkey, tile_type_pkey FROM tile WHERE grid_x = ? AND grid_y = ?;",
            (grid_x, grid_y)
        )
        tile_pkey, tile_type_pkey = cur2.fetchone()

        for site in tile.sites:
            # Find all wires that belong to the new tile location.
            for wire_pkey, wire_in_tile_pkey in cur2.execute("""
WITH wires(wire_pkey, wire_in_tile_pkey) AS (
    SELECT
        pkey, wire_in_tile_pkey
    FROM
        wire
    WHERE
        phy_tile_pkey = ?
)
SELECT
    wires.wire_pkey, wires.wire_in_tile_pkey
FROM
    wires
INNER JOIN
    wire_in_tile
ON
    wire_in_tile.pkey = wires.wire_in_tile_pkey
WHERE
    wire_in_tile.site_pkey = ?
    ;""", (site.phy_tile_pkey, site.site_pkey)):
                # Move the wire to the new tile_pkey.
                write_cur.execute(
                    """
UPDATE
    wire
SET
    tile_pkey = ?
WHERE
    pkey = ?;""", (
                        tile_pkey,
                        wire_pkey,
                    )
                )

                if tile_type_pkey not in wire_in_tile_pkey_to_update:
                    wire_in_tile_pkey_to_update[tile_type_pkey] = set()

                wire_in_tile_pkey_to_update[tile_type_pkey].add(
                    wire_in_tile_pkey
                )

                # Wires connected to the site via a pip require traversing the
                # pip.
                other_wire_in_tile_pkey = traverse_pip(conn, wire_in_tile_pkey)
                if other_wire_in_tile_pkey is not None:
                    cur.execute(
                        """
SELECT classification
FROM node
WHERE pkey = (
    SELECT node_pkey
    FROM wire
    WHERE
        phy_tile_pkey = ?
    AND
        wire_in_tile_pkey = ?
)
                        ;""", (site.phy_tile_pkey, other_wire_in_tile_pkey)
                    )
                    classification = NodeClassification(cur.fetchone()[0])

                    if classification != NodeClassification.CHANNEL:
                        continue

                    # A wire was found connected to the site via pip, reassign
                    # tile_pkey.
                    write_cur.execute(
                        """
UPDATE
    wire
SET
    tile_pkey = ?
WHERE
    phy_tile_pkey = ?
AND
    wire_in_tile_pkey = ?
    ;""", (tile_pkey, site.phy_tile_pkey, other_wire_in_tile_pkey)
                    )

    # Now that final wire <-> tile assignments are made, create the index.
    write_cur.execute(
        "CREATE INDEX tile_wire_index ON wire(wire_in_tile_pkey, tile_pkey, node_pkey);"
    )
    write_cur.execute(
        "CREATE INDEX node_tile_wire_index ON wire(node_pkey, tile_pkey, wire_in_tile_pkey);"
    )

    # Update tile_type_pkey in wire_in_tile table.
    update_wire_in_tile_types(
        cur, write_cur, empty_tile_type_pkey, wire_in_tile_pkey_to_update
    )

    write_cur.execute("""COMMIT TRANSACTION;""")

    write_cur.execute("""BEGIN EXCLUSIVE TRANSACTION;""")
    write_cur.execute("ANALYZE")
    write_cur.execute("""COMMIT TRANSACTION;""")

    # Now that the final VPR grid is generated, we need a fast lookup to easily
    # access to the canonical to VPR grid mapping.
    #
    # Furthermore, information on the internal tile connections between sites belonging
    # to the same tile, which are treated as heterogeneous tiles. These connections are
    # required to correctly instruct VPR on the presence of direct connections between
    # sites at the same X, Y coordinate, but with different sub tile coordinates.
    fieldnames = [
        "site_name",
        "site_type",
        "physical_tile",
        "vpr_x",
        "vpr_y",
        "canon_x",
        "canon_y",
        "clock_region",
        "connected_to_site",
    ]
    csv_writer = csv.DictWriter(grid_map_output, fieldnames=fieldnames)
    csv_writer.writeheader()

    # Find all sites that have direct connections with other sites in the same tile.
    sites_with_direct = dict()
    for src_wire_pkey, dest_wire_pkey, pip_in_tile_pkey in \
            progressbar_utils.progressbar(
            cur.execute("""
SELECT
    src_wire_pkey,
    dest_wire_pkey,
    pip_in_tile_pkey
FROM
    edge_with_mux""")):

        cur2.execute(
            """
SELECT node_pkey FROM wire WHERE pkey = ?""", (src_wire_pkey, )
        )
        (src_node_pkey, ) = cur2.fetchone()

        # Find the wire connected to the source.
        src_wire = list(node_to_site_pins(conn, src_node_pkey))
        assert len(src_wire) == 1
        _, src_tile_pkey, src_wire_in_tile_pkey = src_wire[0]

        cur2.execute(
            """
SELECT tile_type_pkey, grid_x, grid_y FROM tile WHERE pkey = ?""",
            (src_tile_pkey, )
        )

        res = cur2.fetchone()
        src_tile_type_pkey, src_grid_x, src_grid_y = res

        # Get the node that is attached to the sink.
        cur2.execute(
            """
SELECT node_pkey FROM wire WHERE pkey = ?""", (dest_wire_pkey, )
        )
        (dest_node_pkey, ) = cur2.fetchone()

        # Find the wire connected to the sink.
        dest_wire = list(node_to_site_pins(conn, dest_node_pkey))
        assert len(dest_wire) == 1
        _, dest_tile_pkey, dest_wire_in_tile_pkey = dest_wire[0]

        cur2.execute(
            """
SELECT tile_type_pkey, grid_x, grid_y FROM tile WHERE pkey = ?;""",
            (dest_tile_pkey, )
        )

        res = cur2.fetchone()
        dest_tile_type_pkey, dest_grid_x, dest_grid_y = res

        if dest_grid_x == src_grid_x and dest_grid_y == src_grid_y:
            tile = new_grid[(dest_grid_x, dest_grid_y)]

            cur2.execute(
                "SELECT site_pkey FROM wire_in_tile WHERE pkey = ?",
                (src_wire_in_tile_pkey, )
            )
            src_site_pkey = cur2.fetchone()[0]

            cur2.execute(
                "SELECT site_pkey FROM wire_in_tile WHERE pkey = ?",
                (dest_wire_in_tile_pkey, )
            )
            dest_site_pkey = cur2.fetchone()[0]

            src_site_instance = None
            dest_site_instance = None
            for site in tile.sites:
                cur2.execute(
                    "SELECT name FROM site_instance WHERE site_pkey = ? AND phy_tile_pkey = ?"
                    "", (
                        site.site_pkey,
                        site.phy_tile_pkey,
                    )
                )

                res = cur2.fetchone()[0]

                if site.site_pkey == src_site_pkey:
                    src_site_instance = res
                elif site.site_pkey == dest_site_pkey:
                    dest_site_instance = res

            assert src_site_instance and dest_site_instance

            sites_with_direct[src_site_instance] = dest_site_instance

    # Build the Canonical to VPR grid mapping
    for (grid_x, grid_y), tile in new_grid.items():
        for site in tile.sites:
            cur.execute(
                "SELECT name FROM site_instance WHERE site_pkey = ? AND phy_tile_pkey = ?",
                (
                    site.site_pkey,
                    site.phy_tile_pkey,
                )
            )

            site_name = cur.fetchone()[0]

            cur.execute(
                "SELECT name, clock_region_pkey, grid_x, grid_y FROM phy_tile WHERE pkey = ?",
                (site.phy_tile_pkey, )
            )

            phy_tile_name, clock_region, canon_x, canon_y = cur.fetchone()

            cur.execute(
                "SELECT name FROM site_type WHERE pkey = ?",
                (site.site_type_pkey, )
            )

            site_type = cur.fetchone()[0]

            # This is a site which is directly connected to the current site
            # and will be implemented as a sub_tile. This information is relevant
            # to generate correct placement constraints for sub_tiles directly
            # connected within the same physical tile
            connected_to_site = sites_with_direct.get(site_name, None)

            csv_writer.writerow(
                {
                    "site_name": site_name,
                    "site_type": site_type,
                    "physical_tile": phy_tile_name,
                    "vpr_x": grid_x,
                    "vpr_y": grid_y,
                    "canon_x": canon_x,
                    "canon_y": canon_y,
                    "clock_region": clock_region,
                    "connected_to_site": connected_to_site
                }
            )


def create_constant_tracks(conn):
    """ Create two tracks that go to all TIEOFF sites to route constants.

    Returns (vcc_track_to_insert, gnd_track_to_insert), suitable for insert
    via insert_tracks function.

    """

    # Make constant track available to all tiles.
    write_cur = conn.cursor()
    unique_pos = set()
    write_cur.execute('SELECT grid_x, grid_y FROM tile')
    for grid_x, grid_y in write_cur:
        if grid_x == 0 or grid_y == 0:
            continue
        unique_pos.add((grid_x, grid_y))

    write_cur.execute(
        """
INSERT INTO node(classification) VALUES (?)
""", (NodeClassification.CHANNEL.value, )
    )
    vcc_node = write_cur.lastrowid

    write_cur.execute(
        """
INSERT INTO node(classification) VALUES (?)
""", (NodeClassification.CHANNEL.value, )
    )
    gnd_node = write_cur.lastrowid

    conn.commit()

    return create_track(vcc_node,
                        unique_pos), create_track(gnd_node, unique_pos)


def import_segments(conn, db):
    """ Create segment table, use segment definitions from SegmentWireMap.

    Parameters
    ----------
    conn : sqlite3.Connection
        Connection to channels.db

    db : prjxray.Database
        Project X-Ray database object.

    Returns
    -------
    SegmentWireMap

        SegmentWireMap can be used to detect which segment a wire belongs too.

    """
    write_cur = conn.cursor()

    default_segment = "unknown"
    segments = SegmentWireMap(default_segment=default_segment, db=db)

    # Add some additional useful segments that are not part of the wire map
    # (e.g. the global constant networks).
    for extra_segment in [default_segment, VCC_NET, GND_NET]:
        if extra_segment not in segments.get_segments():
            write_cur.execute(
                """
INSERT INTO segment(name) VALUES (?)
            """, (extra_segment, )
            )

    for segment in segments.get_segments():
        write_cur.execute(
            """
INSERT INTO segment(name) VALUES (?)
            """, (segment, )
        )

    write_cur.execute("CREATE INDEX segment_name_map ON segment(name);")
    conn.commit()

    return segments


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--db_root', help='Project X-Ray Database', required=True
    )
    parser.add_argument('--part', help='FPGA part', required=True)
    parser.add_argument(
        '--connection_database', help='Connection database', required=True
    )
    parser.add_argument(
        '--grid_map_output',
        help='Location of the grid map output',
        required=True
    )

    args = parser.parse_args()
    if os.path.exists(args.connection_database):
        os.remove(args.connection_database)

    with DatabaseCache(args.connection_database) as conn:
        create_tables(conn)

        print("{}: About to load database".format(datetime.datetime.now()))
        db = prjxray.db.Database(args.db_root, args.part)
        grid = db.grid()
        get_switch, get_switch_timing = create_get_switch(conn)
        import_phy_grid(db, grid, conn, get_switch, get_switch_timing)

        segments = import_segments(conn, db)

        print("{}: Initial database formed".format(datetime.datetime.now()))
        import_nodes(db, grid, conn)
        print("{}: Connections made".format(datetime.datetime.now()))
        count_sites_and_pips_on_nodes(conn)
        print("{}: Counted sites and pips".format(datetime.datetime.now()))
        classify_nodes(conn, get_switch_timing)
        print("{}: Create VPR grid".format(datetime.datetime.now()))
        with open(args.grid_map_output, 'w') as f:
            create_vpr_grid(conn, f)
        print("{}: Nodes classified".format(datetime.datetime.now()))
        form_tracks(conn, segments)
        print("{}: Tracks formed".format(datetime.datetime.now()))

        print(
            '{} Flushing database back to file "{}"'.format(
                datetime.datetime.now(), args.connection_database
            )
        )


if __name__ == '__main__':
    main()
