#!/usr/bin/env python3

import sys
import os
import lxml.etree as ET

import icebox

from ice40_list_layout_in_icebox import versions


def vpr_pos(x, y):
    return x + 2, y + 2


def get_corner_tiles(ic):
    corner_tiles = set()
    for x in (0, ic.max_x):
        for y in (0, ic.max_y):
            corner_tiles.add((x, y))
    return corner_tiles


def add_metadata(parent_xml, key, value):
    metadata_xml = parent_xml.find("./metadata")
    if metadata_xml is None:
        metadata_xml = ET.SubElement(parent_xml, "metadata")

    m = ET.SubElement(metadata_xml, "meta", {"name": str(key)})
    m.text = str(value)


def add_tile(layout_xml, type_name, pos):
    return ET.SubElement(
        layout_xml, "single", {
            'type': type_name,
            'x': str(pos[0]),
            'y': str(pos[1]),
            'priority': '1'
        }
    )


SKIP = []

for name, pins in icebox.pinloc_db.items():
    part, package = name.split('-')
    if ':' in package:
        continue
    #if part != "1k":
    #    continue
    pin_locs = {}
    for name, x, y, z in pins:
        if (x, y) not in pin_locs:
            pin_locs[(x, y)] = {}
        pin_locs[(x, y)][z] = name

    ic = icebox.iceconfig()
    getattr(ic, "setup_empty_{}".format(part))()

    def edge_blocks(x, y):
        p = [[0, 0], [0, 0], [0, 0]]
        if x == 0:
            p[0][0] -= 1
            p[1][0] -= 1
        if x == ic.max_x:
            p[0][0] += 1
            p[1][0] += 1
        if y == 0:
            p[1][1] -= 1
            p[2][1] -= 1
        if y == ic.max_y:
            p[1][1] += 1
            p[2][1] += 1
        p = set(tuple(x) for x in p)
        try:
            p.remove((0, 0))
        except KeyError:
            pass
        return tuple(p)

    def find_fabric_glb_netwk(x, y):
        fabric_glb_network = ""
        for gx, gy, gn in ic.gbufin_db():
            if (gx, gy) == (x, y):
                fabric_glb_network = "glb_netwk_{}".format(gn)
        return fabric_glb_network

    def tile_type(x, y):
        tt = ic.tile_type(x, y)

        if tt == "IO":
            fasm_prefix = ""
            for z in range(2):
                fasm_prefix += "{}_X{:d}_Y{:d}.IOB_{:d} ".format(tt, x, y, z)
        else:
            fasm_prefix = "{}_X{:d}_Y{:d}".format(tt, x, y)

        metadata = {
            'hlc_coord': "{:d} {:d}".format(x, y),
            "fasm_prefix": fasm_prefix
        }
        if (x, y) in get_corner_tiles(ic):
            return None, {}
        if tt == "RAMB":
            return "RAM", metadata
        if tt == "RAMT":
            return SKIP, {}
        if tt.startswith("DSP"):
            if tt.endswith("0"):
                return "DSP", metadata
            return SKIP, {}
        if tt == "IO":
            padin = ic.padin_pio_db()

            details = []
            for z in (0, 1):
                try:
                    metadata["hlc_global_io:{}".format(z)
                             ] = "glb_netwk_{}".format(padin.index((x, y, z)))
                    metadata["hlc_global_fabric:{}".format(z)
                             ] = find_fabric_glb_netwk(x, y)
                    tt = "GPIO{}".format(z)
                except ValueError:
                    pass

                name = ""
                if (x, y) in pin_locs:
                    tile = pin_locs[(x, y)]
                    if z in tile:
                        name = tile[z]

                if (x, y) in ic.iolatch_db():
                    metadata["hlc_latch_io"] = z

                print(
                    "(%2d,%2d)-%d i:%12s f:%12s l:%2s n:%s" % (
                        x, y, z,
                        metadata.get("hlc_global_io:{}".format(z), ""),
                        metadata.get("hlc_global_fabric:{}".format(z), ""),
                        metadata.get("hlc_latch_io", ""), name
                    )
                )
            return "PIO", metadata
        if tt == "LOGIC":
            return "PLB", metadata
        return None, {}
        assert False, tt

    for version in versions(part):
        layout_xml = ET.Element(
            "fixed_layout", {
                'name': '{}-{}'.format(version, package),
                'width': str(ic.max_x + 4 + 1),
                'height': str(ic.max_y + 4 + 1),
            }
        )

        pin_map = {}
        for x in range(0, ic.max_x + 1):
            for y in range(0, ic.max_y + 1):
                ipos = (x, y)
                vpos = vpr_pos(*ipos)

                tt, metadata = tile_type(*ipos)
                if tt is not None:
                    if tt is not SKIP:
                        tile_xml = add_tile(layout_xml, tt, vpos)
                else:
                    tile_xml = add_tile(layout_xml, "EMPTY", vpos)

                for k, v in metadata.items():
                    add_metadata(tile_xml, k, str(v))

                eposes = edge_blocks(x, y)
                #print(vpos, eposes)
                for e in eposes:
                    pad_xml = add_tile(
                        layout_xml, "EMPTY",
                        (vpos[0] + e[0] * 2, vpos[1] + e[1] * 2)
                    )

                    pin_pos = vpos[0] + e[0] * 1, vpos[1] + e[1] * 1
                    if ipos in pin_locs:
                        pin_xml = add_tile(layout_xml, "EMPTY", pin_pos)
                        for z, name in pin_locs[ipos].items():
                            add_metadata(pin_xml, "hlc_pin:{}".format(z), name)
                            pin_map[(*vpos, z)] = name
                    else:
                        pin_xml = add_tile(layout_xml, "EMPTY", pin_pos)

                    add_metadata(
                        pin_xml, "hlc_coord",
                        "{} {}".format(x + e[0], y + e[1])
                    )

        with open("{}.{}.fixed_layout.xml".format(version, package),
                  "wb+") as f:
            f.write(ET.tostring(layout_xml, pretty_print=True))

        def i(x):
            try:
                return int(x)
            except ValueError:
                return x

        lines = [(i(v), *k) for k, v in pin_map.items()]
        with open("{}.{}.pinmap.csv".format(version, package), "wb+") as f:
            f.write("name,x,y,z\n".format(*k, v).encode("utf-8"))
            for i in sorted(lines):
                f.write("{},{},{},{}\n".format(*i).encode("utf-8"))
