#!/usr/bin/env python3
"""
This script allows to read the tile grid from various sources and render it to
either SVG or PDF file. It can also draw connections between tiles when
provided with the 'tileconn.json' file used in the prjxray database.

Use ONE of following argument sets for data source specification:
1. --tilgrid <tilegrid.json> [--tileconn <tileconn.json>]
2. --arch-xml <arch.xml>
3. --graph-xml <rr_graph.xml>
4. --conn-db <channels.db> [--tb-table <tile table name>]
"""

import sys
import argparse
import os
import re
from collections import namedtuple

import progressbar

import json
import sqlite3

import lxml.etree as ET
import lxml.objectify as objectify

import svgwrite

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


class GridVisualizer(object):

    BLOCK_RECT = 100
    BLOCK_GAP = 10
    BLOCK_SIZE = BLOCK_RECT + BLOCK_GAP

    Loc = namedtuple("Loc", "x y")
    Conn = namedtuple("Conn", "loc0 loc1")
    GridExtent = namedtuple("GridExtent", "xmin ymin xmax ymax")

    def __init__(self):

        self.tilegrid = None
        self.tileconn = None

        self.grid_roi = None
        self.conn_roi = None

        self.tile_colormap = None
        self.connections = {}

    def load_tilegrid_from_json(self, json_file):

        # Load JSON files
        with open(json_file, "r") as fp:
            self.tilegrid = json.load(fp)

        self._determine_grid_extent()
        self._build_loc_map()

    def load_tileconn_from_json(self, json_file):

        # Load JSON files
        with open(json_file, "r") as fp:
            self.tileconn = json.load(fp)

        self._form_connections()

    def load_tilegrid_from_arch_xml(self, xml_file):

        # Load and parse the XML
        parser = ET.XMLParser(remove_comments=True)
        xml_tree = objectify.parse(xml_file, parser=parser)
        xml_root = xml_tree.getroot()

        # Get the layout section
        layout = xml_root.find("layout")
        assert (layout is not None)

        # Get the fixed_layout section
        fixed_layout = layout.find("fixed_layout")
        assert (fixed_layout is not None)

        # Extract the grid extent
        dx = int(fixed_layout.get("width"))
        dy = int(fixed_layout.get("height"))
        self.grid_extent = self.GridExtent(0, 0, dx, dy)

        # Convert
        self.tilegrid = {}

        for tile in list(fixed_layout):
            assert (tile.tag == "single")

            # Basic tile parameters
            grid_x = int(tile.get("x"))
            grid_y = int(tile.get("y"))
            tile_type = tile.get("type")

            # Tile name (if present)
            tile_name = None
            metadata = tile.find("metadata")
            if metadata is not None:
                for meta in metadata.findall("meta"):
                    if meta.get("name") == "fasm_prefix":
                        tile_name = meta.text

            # Fake tile name
            if tile_name is None:
                tile_name = "UNKNOWN_X%dY%d" % (grid_x, grid_y)

            # Already exists
            if tile_name in self.tilegrid:
                tile_name += "(2)"

            self.tilegrid[tile_name] = {
                "grid_x": grid_x,
                "grid_y": grid_y,
                "type": tile_type
            }

        self._build_loc_map()

    def load_tilegrid_from_graph_xml(self, xml_file):

        # Load and parse the XML
        parser = ET.XMLParser(remove_comments=True)
        xml_tree = objectify.parse(xml_file, parser=parser)
        xml_root = xml_tree.getroot()

        # Load block types
        xml_block_types = xml_root.find("block_types")
        assert (xml_block_types is not None)

        block_types = {}
        for xml_block_type in xml_block_types:
            block_type_id = int(xml_block_type.get("id"))
            block_name = xml_block_type.get("name")

            block_types[block_type_id] = block_name

        # Load grid
        self.tilegrid = {}

        all_x = set()
        all_y = set()

        xml_grid = xml_root.find("grid")
        assert (xml_grid is not None)

        for xml_grid_loc in xml_grid:
            grid_x = int(xml_grid_loc.get("x"))
            grid_y = int(xml_grid_loc.get("y"))
            block_type_id = int(xml_grid_loc.get("block_type_id"))

            all_x.add(grid_x)
            all_y.add(grid_y)

            # Fake tile name
            tile_name = "BLOCK_X%dY%d" % (grid_x, grid_y)

            self.tilegrid[tile_name] = {
                "grid_x": grid_x,
                "grid_y": grid_y,
                "type": block_types[block_type_id]
            }

        # Determine grid extent
        self.grid_extent = self.GridExtent(
            min(all_x), min(all_y), max(all_x), max(all_y)
        )

        self._build_loc_map()

    def load_tilegrid_from_conn_db(self, db_file, db_table):

        # Connect to the database and load data
        with sqlite3.Connection("file:%s?mode=ro" % db_file, uri=True) as conn:
            c = conn.cursor()

            # Load the grid
            db_tiles = c.execute(
                "SELECT pkey, name, tile_type_pkey, grid_x, grid_y FROM %s" %
                (db_table)
            ).fetchall()  # They say that it is insecure..

            # Load tile types
            db_tile_types = c.execute("SELECT pkey, name FROM tile_type"
                                      ).fetchall()

        # Maps pkey to type string
        tile_type_map = {}
        for item in db_tile_types:
            tile_type_map[item[0]] = item[1]

        # Translate information
        self.tilegrid = {}

        all_x = set()
        all_y = set()

        for tile in db_tiles:

            tile_type_pkey = tile[2]

            if tile_type_pkey not in tile_type_map.keys():
                print("Unknown tile type pkey %d !" % tile_type_pkey)
                continue

            tile_name = tile[1]
            tile_type = tile_type_map[tile_type_pkey]
            tile_grid_x = tile[3]
            tile_grid_y = tile[4]

            if tile_name in self.tilegrid:
                print("Duplicate tile name '%s' !" % tile_name)
                continue

            all_x.add(tile_grid_x)
            all_y.add(tile_grid_y)

            self.tilegrid[tile_name] = {
                "grid_x": tile_grid_x,
                "grid_y": tile_grid_y,
                "type": tile_type
            }

        # Determine grid extent
        self.grid_extent = self.GridExtent(
            min(all_x), min(all_y), max(all_x), max(all_y)
        )

        self._build_loc_map()

    def load_tile_colormap(self, colormap):

        # If it fails just skip it
        try:
            with open(colormap, "r") as fp:
                self.tile_colormap = json.load(fp)

        except FileNotFoundError:
            pass

    def set_grid_roi(self, roi):
        self.grid_roi = roi

    def set_conn_roi(self, roi):
        self.conn_roi = roi

    def _determine_grid_extent(self):

        # Determine the grid extent
        xs = set()
        ys = set()

        for tile in self.tilegrid.values():
            xs.add(tile["grid_x"])
            ys.add(tile["grid_y"])

        self.grid_extent = self.GridExtent(min(xs), min(ys), max(xs), max(ys))

        if self.grid_roi is not None:
            self.grid_extent = self.GridExtent(
                max(self.grid_extent.xmin, self.grid_roi[0]),
                max(self.grid_extent.ymin, self.grid_roi[1]),
                min(self.grid_extent.xmax, self.grid_roi[2]),
                min(self.grid_extent.ymax, self.grid_roi[3])
            )

    def _build_loc_map(self):

        self.loc_map = {}

        for tile_name, tile in self.tilegrid.items():
            loc = self.Loc(tile["grid_x"], tile["grid_y"])

            if loc in self.loc_map.keys():
                print("Duplicate tile at [%d, %d] !" % (loc.x, loc.y))

            self.loc_map[loc] = tile_name

    def _form_connections(self):

        # Loop over tiles of interest
        print("Forming connections...")
        for tile_name, tile in progressbar.progressbar(self.tilegrid.items()):

            this_loc = self.Loc(tile["grid_x"], tile["grid_y"])
            this_type = tile["type"]

            # Find matching connection rules
            for rule in self.tileconn:
                grid_deltas = rule["grid_deltas"]
                tile_types = rule["tile_types"]
                wire_count = len(rule["wire_pairs"])

                for k in [+1]:

                    # Get a couterpart tile according to the rule grid delta
                    other_loc = self.Loc(
                        this_loc.x + k * grid_deltas[0],
                        this_loc.y + k * grid_deltas[1]
                    )

                    try:
                        other_name = self.loc_map[other_loc]
                        other_type = self.tilegrid[other_name]["type"]
                    except KeyError:
                        continue

                    # Check match
                    if this_type == tile_types[0] and \
                       other_type == tile_types[1]:

                        # Add the connection
                        conn = self.Conn(this_loc, other_loc)

                        if conn not in self.connections.keys():
                            self.connections[conn] = wire_count
                        else:
                            self.connections[conn] += wire_count

    def _draw_connection(self, x0, y0, x1, y1, curve=False):

        if curve:
            dx = x1 - x0
            dy = y1 - y0

            cx = (x1 + x0) * 0.5 + dy * 0.33
            cy = (y1 + y0) * 0.5 - dx * 0.33

            path = "M %.3f %.3f " % (x0, y0)
            path += "C %.3f %.3f %.3f %.3f %.3f %.3f" % \
                (cx, cy, cx, cy, x1, y1)

            self.svg.add(self.svg.path(d=path, fill="none", stroke="#000000"))

        else:
            self.svg.add(self.svg.line((x0, y0), (x1, y1), stroke="#000000"))

    def _grid_to_drawing(self, x, y):

        xc = (x - self.grid_extent.xmin + 1) * self.BLOCK_SIZE
        yc = (y - self.grid_extent.ymin + 1) * self.BLOCK_SIZE

        return xc, yc

    def _create_drawing(self):

        # Drawing size
        self.svg_dx = (self.grid_extent.xmax - self.grid_extent.xmin + 2) \
            * self.BLOCK_SIZE
        self.svg_dy = (self.grid_extent.ymax - self.grid_extent.ymin + 2) \
            * self.BLOCK_SIZE

        # Create the drawing
        self.svg = svgwrite.Drawing(
            size=(self.svg_dx, self.svg_dy), profile="full", debug=False
        )

    def _get_tile_color(self, tile_name, tile):
        tile_type = tile["type"]

        # Match
        if self.tile_colormap is not None:
            for rule in self.tile_colormap:

                # Match by tile name
                if "name" in rule and re.match(rule["name"], tile_name):
                    return rule["color"]
                # Match by tile type
                if "type" in rule and re.match(rule["type"], tile_type):
                    return rule["color"]

        # A default color
        return "#C0C0C0"

    def _draw_grid(self):

        svg_tiles = []
        svg_text = []

        # Draw tiles
        print("Drawing grid...")
        for tile_name, tile in progressbar.progressbar(self.tilegrid.items()):

            grid_x = tile["grid_x"]
            grid_y = tile["grid_y"]
            tile_type = tile["type"]

            if self.grid_roi:
                if grid_x < self.grid_roi[0] or grid_x > self.grid_roi[2]:
                    continue
                if grid_y < self.grid_roi[1] or grid_y > self.grid_roi[3]:
                    continue

            xc, yc = self._grid_to_drawing(grid_x, grid_y)

            color = self._get_tile_color(tile_name, tile)
            if color is None:
                continue

            font_size = self.BLOCK_RECT / 10

            # Rectangle
            svg_tiles.append(
                self.svg.rect(
                    (
                        xc - self.BLOCK_RECT / 2,
                        (self.svg_dy - 1 - yc) - self.BLOCK_RECT / 2
                    ), (self.BLOCK_RECT, self.BLOCK_RECT),
                    stroke="#C0C0C0",
                    fill=color
                )
            )

            if grid_x & 1:
                text_ofs = -font_size
            else:
                text_ofs = font_size

            # Tile name
            svg_text.append(
                self.svg.text(
                    tile_name, (
                        xc - self.BLOCK_RECT / 2 + 2,
                        (self.svg_dy - 1 - yc) - font_size / 2 + text_ofs
                    ),
                    font_size=font_size
                )
            )
            # Tile type
            svg_text.append(
                self.svg.text(
                    tile_type, (
                        xc - self.BLOCK_RECT / 2 + 2,
                        (self.svg_dy - 1 - yc) + font_size / 2 + text_ofs
                    ),
                    font_size=font_size
                )
            )

            # Index
            svg_text.append(
                self.svg.text(
                    "X%dY%d" % (grid_x, grid_y), (
                        xc - self.BLOCK_RECT / 2 + 2,
                        (self.svg_dy - 1 - yc) + self.BLOCK_RECT / 2 - 2
                    ),
                    font_size=font_size
                )
            )

        # Add tiles to SVG
        for item in svg_tiles:
            self.svg.add(item)

        # Add text to SVG
        for item in svg_text:
            self.svg.add(item)

    def _draw_connections(self):

        # Draw connections
        print("Drawing connections...")
        for conn, count in progressbar.progressbar(self.connections.items()):

            if self.conn_roi:

                if conn.loc0.x < self.grid_roi[0] or \
                   conn.loc0.x > self.grid_roi[2]:
                    if conn.loc1.x < self.grid_roi[0] or \
                       conn.loc1.x > self.grid_roi[2]:
                        continue

                if conn.loc0.y < self.grid_roi[1] or \
                   conn.loc0.y > self.grid_roi[3]:
                    if conn.loc1.y < self.grid_roi[1] or \
                       conn.loc1.y > self.grid_roi[3]:
                        continue

            dx = conn.loc1.x - conn.loc0.x
            dy = conn.loc1.y - conn.loc0.y

            xc0, yc0 = self._grid_to_drawing(conn.loc0.x, conn.loc0.y)
            xc1, yc1 = self._grid_to_drawing(conn.loc1.x, conn.loc1.y)

            max_count = int(self.BLOCK_RECT * 0.75 * 0.5)
            line_count = min(count, max_count)

            # Mostly horizontal
            if abs(dx) > abs(dy):

                for i in range(line_count):
                    k = 0.5 if line_count == 1 else i / (line_count - 1)
                    k = (k - 0.5) * 0.75

                    if dx > 0:
                        x0 = xc0 + self.BLOCK_RECT / 2
                        x1 = xc1 - self.BLOCK_RECT / 2
                    else:
                        x0 = xc0 - self.BLOCK_RECT / 2
                        x1 = xc1 + self.BLOCK_RECT / 2

                    y0 = yc0 + k * self.BLOCK_RECT
                    y1 = yc1 + k * self.BLOCK_RECT

                    self._draw_connection(
                        x0, (self.svg_dy - 1 - y0), x1, (self.svg_dy - 1 - y1),
                        True
                    )

            # Mostly vertical
            elif abs(dy) > abs(dx):

                for i in range(line_count):
                    k = 0.5 if line_count == 1 else i / (line_count - 1)
                    k = (k - 0.5) * 0.75

                    if dy > 0:
                        y0 = yc0 + self.BLOCK_RECT / 2
                        y1 = yc1 - self.BLOCK_RECT / 2
                    else:
                        y0 = yc0 - self.BLOCK_RECT / 2
                        y1 = yc1 + self.BLOCK_RECT / 2

                    x0 = xc0 + k * self.BLOCK_RECT
                    x1 = xc1 + k * self.BLOCK_RECT

                    self._draw_connection(
                        x0, (self.svg_dy - 1 - y0), x1, (self.svg_dy - 1 - y1),
                        True
                    )

            # Diagonal
            else:
                # FIXME: Do it in a more elegant way...

                max_count = int(max_count * 0.40)
                line_count = min(count, max_count)

                for i in range(line_count):
                    k = 0.5 if line_count == 1 else i / (line_count - 1)
                    k = (k - 0.5) * 0.25

                    if (dx > 0) ^ (dy > 0):
                        x0 = xc0 + k * self.BLOCK_RECT
                        x1 = xc1 + k * self.BLOCK_RECT
                        y0 = yc0 + k * self.BLOCK_RECT
                        y1 = yc1 + k * self.BLOCK_RECT
                    else:
                        x0 = xc0 - k * self.BLOCK_RECT
                        x1 = xc1 - k * self.BLOCK_RECT
                        y0 = yc0 + k * self.BLOCK_RECT
                        y1 = yc1 + k * self.BLOCK_RECT

                    x0 += dx * self.BLOCK_RECT / 4
                    y0 += dy * self.BLOCK_RECT / 4
                    x1 -= dx * self.BLOCK_RECT / 4
                    y1 -= dy * self.BLOCK_RECT / 4

                    self._draw_connection(
                        x0, (self.svg_dy - 1 - y0), x1, (self.svg_dy - 1 - y1),
                        False
                    )

    def run(self):

        if self.grid_roi is not None:

            if self.conn_roi is None:
                self.conn_roi = self.grid_roi
            else:
                self.conn_roi[0] = max(self.conn_roi[0], self.grid_roi[0])
                self.conn_roi[1] = max(self.conn_roi[1], self.grid_roi[1])
                self.conn_roi[2] = min(self.conn_roi[2], self.grid_roi[2])
                self.conn_roi[3] = min(self.conn_roi[3], self.grid_roi[3])

        self._create_drawing()
        self._draw_grid()
        self._draw_connections()

    def save(self, file_name):
        self.svg.saveas(file_name)


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


def main():

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

    parser.add_argument(
        "--tilegrid",
        type=str,
        default=None,
        help="Project X-Ray 'tilegrid.json' file"
    )
    parser.add_argument(
        "--tileconn",
        type=str,
        default=None,
        help="Project X-Ray 'tileconn.json' file"
    )
    parser.add_argument(
        "--arch-xml",
        type=str,
        default=None,
        help="Architecture definition XML file"
    )
    parser.add_argument(
        "--graph-xml", type=str, default=None, help="Routing graph XML file"
    )
    parser.add_argument(
        '--conn-db',
        type=str,
        default=None,
        help='Connection SQL database (eg. "channels.db")'
    )
    parser.add_argument(
        '--db-table',
        type=str,
        default="tile",
        help='Table name in the SQL database to read (def. "tile")'
    )
    parser.add_argument(
        "--colormap",
        type=str,
        default=None,
        help="JSON file with tile coloring rules"
    )
    parser.add_argument(
        "--grid-roi",
        type=int,
        nargs=4,
        default=None,
        help="Grid ROI to draw (x0 y0 x1 y1)"
    )
    parser.add_argument(
        "--conn-roi",
        type=int,
        nargs=4,
        default=None,
        help="Connection ROI to draw (x0 y0 x1 y1)"
    )
    parser.add_argument(
        "-o", type=str, default="layout.svg", help="Output SVG file name"
    )

    if len(sys.argv) <= 1:
        parser.print_help()
        exit(1)

    args = parser.parse_args()

    script_path = os.path.dirname(os.path.realpath(__file__))
    if args.colormap is None:
        args.colormap = os.path.join(script_path, "tile_colormap.json")

    # Create the visualizer
    visualizer = GridVisualizer()

    # Set ROI
    visualizer.set_grid_roi(args.grid_roi)
    visualizer.set_conn_roi(args.conn_roi)

    # Load arch XML file
    if args.arch_xml is not None:
        visualizer.load_tilegrid_from_arch_xml(args.arch_xml)
    # Load routing graph XML
    elif args.graph_xml is not None:
        visualizer.load_tilegrid_from_graph_xml(args.graph_xml)
    # Load JSON files
    elif args.tilegrid is not None:

        visualizer.load_tilegrid_from_json(args.tilegrid)

        if args.tileconn is not None:
            visualizer.load_tileconn_from_json(args.tileconn)
    # Load SQL database
    elif args.conn_db is not None:
        visualizer.load_tilegrid_from_conn_db(args.conn_db, args.db_table)

    # No data input
    else:
        raise RuntimeError("No input data specified")

    # Load tile colormap
    if args.colormap:
        visualizer.load_tile_colormap(args.colormap)

    # Do the visualization
    visualizer.run()

    # Save drawing
    if args.o.endswith(".svg"):
        print("Saving SVG...")
        visualizer.save(args.o)

    elif args.o.endswith(".pdf"):
        print("Saving PDF...")

        from cairosvg import svg2pdf
        svg2pdf(visualizer.svg.tostring(), write_to=args.o)

    else:
        print("Unknown output file type '{}'".format(args.o))
        exit(-1)

    print("Done.")


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

if __name__ == "__main__":
    main()
