""" Grid splitting model with connection database back references.

The Grid object provides methods to manipulate a 2D grid of Tile objects, that
contain zero or more Site objects. Site objects are considered immutable.

To construct the Grid object, the initial grid and an empty_tile_type_pkey must
be provided.  The initial grid should be provided as a map of 2 element int
tuples to Tile objects.  Tile objects should already contain their initial
sites prior to construction of the Grid object.

"""
from enum import Enum
from collections import namedtuple


class Direction(Enum):
    """ Grid directions. """
    NORTH = 1
    SOUTH = 2
    EAST = 3
    WEST = 4


NORTH = Direction.NORTH
SOUTH = Direction.SOUTH
EAST = Direction.EAST
WEST = Direction.WEST

OPPOSITE_DIRECTIONS = {
    NORTH: SOUTH,
    SOUTH: NORTH,
    EAST: WEST,
    WEST: EAST,
}

# Zipper direction when splitting in a direction
SPLIT_NEXT_DIRECTIONS = {
    NORTH: EAST,
    SOUTH: EAST,
    EAST: SOUTH,
    WEST: SOUTH,
}


def opposite_direction(direction):
    """ Return opposite direction of given direction.

    >>> opposite_direction(NORTH)
    <Direction.SOUTH: 2>
    >>> opposite_direction(SOUTH)
    <Direction.NORTH: 1>
    >>> opposite_direction(EAST)
    <Direction.WEST: 4>
    >>> opposite_direction(WEST)
    <Direction.EAST: 3>

    """
    return OPPOSITE_DIRECTIONS[direction]


# Right handed coordinate system, N/S in y, E/W in x, E is x-positive,
# S is y-positive.
DIRECTION_OFFSET = {
    NORTH: [0, -1],
    SOUTH: [0, 1],
    EAST: [1, 0],
    WEST: [-1, 0],
}


def coordinate_in_direction(coord, direction):
    """ Given a coordinate, returns a new coordinate 1 step in direction.

    Coordinate system is right handed, N/S in y, E/W in x.  E is x-positive.
    S is y-positive.

    Parameters
    ----------
    coord : Tuple of 2 ints
        Starting coordinate
    direction : Direction
        Direction to add unit vector.

    Returns
    -------
    Tuple of 2 ints
        Coordinate 1 unit step in specified direction.  Will return none if
        x or y coordinate is negative.

    Examples
    --------

    >>> coordinate_in_direction((0, 0), SOUTH)
    (0, 1)
    >>> coordinate_in_direction((0, 0), EAST)
    (1, 0)
    >>> coordinate_in_direction((1, 1), SOUTH)
    (1, 2)
    >>> coordinate_in_direction((1, 1), NORTH)
    (1, 0)
    >>> coordinate_in_direction((1, 1), EAST)
    (2, 1)
    >>> coordinate_in_direction((1, 1), WEST)
    (0, 1)

    # Returns None for negative coordinates.
    >>> coordinate_in_direction((0, 0), NORTH)
    >>> coordinate_in_direction((1, 0), NORTH)
    >>> coordinate_in_direction((0, 0), WEST)
    >>> coordinate_in_direction((0, 1), WEST)

    """
    x, y = coord
    dx, dy = DIRECTION_OFFSET[direction]
    x += dx
    y += dy

    if x < 0 or y < 0:
        return None
    else:
        return x, y


class Site(namedtuple('Site', ('name', 'phy_tile_pkey', 'tile_type_pkey',
                               'site_type_pkey', 'site_pkey', 'x', 'y'))):
    """ Object to hold back reference information for a site. """
    pass


class Tile(object):
    """ Tile instance within the grid.

    Attributes
    ----------
    root_phy_tile_pkeys : list of ints
        The list of root_phy_tile_pkey's.

        By default a tile typically has one root phy_tile_pkey, which is the
        phy_tile this initial represents.

        If two Tile objects are merged, the root_phy_tile_pkeys are also merged.
        If a Tile object is split, only one of the split tiles will take all
        of the root_phy_tile_pkeys, and the other tiles will have no
        root_phy_tile_pkeys.

        Invariant: Each phy_tile_pkey will appear in 1 and only 1 Tile
        object's root_phy_tile_pkeys list.

        Because of the invariant, the root_phy_tile_pkeys list can be used as
        a default assignment of children of the relevant phy_tile_pkey items
        (e.g. wires, pips, sites, etc).

    phy_tile_pkeys : list of ints
        The list of phy_tile_pkey's.  This is the list of all phy_tile_pkey's
        that are involved in this tile via either a tile merge or split.

        By default a tile typically has one phy_tile_pkey, which is the
        phy_tile this initial represents.

        If two Tile objects are split, all output tiles will get a copy of the
        original phy_tile_pkeys list.  This attribute can be used to determine
        what phy_tile_pkeys were used to make this tile.

    sites : list of Site objects
        This is the list of Site's contained within this tile.  This should
        be initial set to the Site objects contained within the original
        phy_tile.

        Invariant: Each Site object will be contained within exactly one Tile
        object.

    split_sites : boolean
        True if this tile was split.

        Invariant: Each split tile will contain exactly one Site object.
        Invariant: Two tiles that were split cannot be merged, otherwise the
        resulting Tile will have two Sites, potentially from different
        phy_tile_pkey, which cannot be presented using FASm prefixes.

    neighboors : Map of Direction to Tile object
        Linked list pointers to neighboors tiles.

        Invariant: Underlying linked link should be rectangular after an
        operation on the grid.  An single operation on the Tile will typically
        invalidate the overall grid, it is up to the Grid object to enforce
        the rectangular constraint.

        Invariant: Underlying linked link must not be circular.

    """

    def __init__(
            self, root_phy_tile_pkeys, phy_tile_pkeys, tile_type_pkey, sites
    ):
        self.root_phy_tile_pkeys = root_phy_tile_pkeys
        self.phy_tile_pkeys = phy_tile_pkeys
        self.tile_type_pkey = tile_type_pkey
        self.sites = sites
        self.split_sites = False
        self.neighboors = {}

    def link_neighboor_in_direction(self, other_tile, direction_to_other_tile):
        """ Connect this tile to another tile in a specific direction.

        It is legal to call this method on an existing connection, but it is
        not legal to call this method to replace an existing connection.

        Parameters
        ----------
        other_tile : Tile object
            Other Tile object to connect in specified direction.
        direction_to_other_tile : Direction
            Direction to connect other tile.
        """
        if direction_to_other_tile in self.neighboors:
            assert id(
                self.neighboors[direction_to_other_tile]
            ) == id(other_tile), (self.neighboors, direction_to_other_tile)
        self.neighboors[direction_to_other_tile] = other_tile

        direction_to_this_tile = opposite_direction(direction_to_other_tile)
        if direction_to_this_tile in other_tile.neighboors:
            assert id(other_tile.neighboors[direction_to_this_tile]
                      ) == id(self)

        other_tile.neighboors[direction_to_this_tile] = self

    def insert_in_direction(self, other_tile, direction_to_other_tile):
        """ Insert a tile in a specified direction.

        Parameters
        ----------
        other_tile : Tile object
            Other Tile object to insert in specified direction.
        direction_to_other_tile : Direction
            Direction to insert other tile.

        """
        old_neighboor = self.neighboors.get(direction_to_other_tile, None)

        direction_to_this_tile = opposite_direction(direction_to_other_tile)

        self.neighboors[direction_to_other_tile] = other_tile
        other_tile.neighboors[direction_to_this_tile] = self

        if old_neighboor is not None:
            other_tile.neighboors[direction_to_other_tile] = old_neighboor
            old_neighboor.neighboors[direction_to_this_tile] = other_tile

    def walk_in_direction(self, direction):
        """ Walk in specified direction from this Tile node.

        Parameters
        ----------

        direction : Direction
            Direction to walk in.

        Yields
        ------

        tile : Tile
            Tile in specified direction.  First Tile object will always be the
            tile whose walk_in_direction was invoked.  When the end of the grid
            is encounted, no more tiles will be yielded.
        """

        node = self

        while True:
            yield node
            if direction in node.neighboors:
                node = node.neighboors[direction]
            else:
                break


def check_grid_loc(grid_loc_map):
    """ Verifies input grid makes sense.

    Internal grid consistency is defined as:
     - Has an origin location @ (0, 0)
     - Is rectangular
     - Has no gaps.

    Parameters
    ----------
    grid_loc_map : Dict of 2 int tuple to Tile objects
        Grid being checked.

    Raises
    ------
    AssertionError
        If provided grid does not conform to assumptions about grid.

    """
    xs, ys = zip(*grid_loc_map.keys())

    max_x = max(xs)
    max_y = max(ys)

    for x in range(max_x + 1):
        for y in range(max_y + 1):
            assert (x, y) in grid_loc_map, (x, y)


def build_mesh(current, visited, loc, grid_loc_map):
    """ Stitch grid_loc_map into a double-linked list 2D mesh.

    Modifies Tile object neighboors attributes to form a doubly linked list
    2D mesh.

    It is strongly recommended that grid_loc_map be passed to check_grid_loc
    prior to calling build_mesh to verify grid invariants.

    Parameters
    ----------
    current : Tile object
    visited : set of python object id's
        Should be empty on root invocation.
    loc : Location of current Tile object argument
    grid_loc_map : Dict of 2 int tuple to Tile objects
        Grid being converted to linked list form.

    """

    for direction in (SOUTH, EAST):
        new_loc = coordinate_in_direction(loc, direction)
        if new_loc in grid_loc_map:
            current.link_neighboor_in_direction(
                grid_loc_map[new_loc], direction
            )
            if id(grid_loc_map[new_loc]) not in visited:
                visited.add(id(grid_loc_map[new_loc]))
                build_mesh(
                    grid_loc_map[new_loc], visited, new_loc, grid_loc_map
                )


class Grid(object):
    """ Object for manipulating a 2D grid of Tile objects.

    Parameters
    ----------

    grid_loc_map : Dict of 2 int tuple to Tile objects
        Initial grid of Tile objects.
    empty_tile_type_pkey : int
        tile_type_pkey to use when creating new empty tiles during tile splits.

    """

    def __init__(self, grid_loc_map, empty_tile_type_pkey):
        # Make sure initial grid is sane
        check_grid_loc(grid_loc_map)

        # Keep root object of grid.
        self.origin = grid_loc_map[(0, 0)]

        # Convert grid to doubly-linked list.
        build_mesh(self.origin, set(), (0, 0), grid_loc_map)

        # Keep list of all Tile objects for convience.
        self.items = grid_loc_map.values()

        self.empty_tile_type_pkey = empty_tile_type_pkey

    def column(self, x):
        """ Return Tile object at top of column.

        Parameters
        ----------
        x : int
            0 based column to retrive.

        Returns
        -------
        top_of_column : Tile
            Tile object at top of column

        """
        top_of_column = self.origin

        for _ in range(x):
            top_of_column = top_of_column.neighboors[EAST]

        return top_of_column

    def row(self, y):
        """ Return Tile object at right of row.

        Parameters
        ----------
        y : int
            0 based row to retrive.

        Returns
        -------
        right_of_row : Tile
            Tile object at right of row

        """
        right_of_row = self.origin

        for _ in range(y):
            right_of_row = right_of_row.neighboors[SOUTH]

    def split_tile(self, tile, tile_type_pkeys, split_direction, split_map):
        """ Split tile in specified direction.

        This method requires that the tiles required to perform the split (e.g.
        len(tile_type_pkeys)-1 tiles in split_direction from tile) have
        tile_type_pkey == empty_tile_type_pkey, e.g. they are empty tiles.

        If empty tiles must be inserted into the grid to accomidate the split,
        this must be done prior to calling this method.

        Parameters
        ----------
        tile : Tile object
            Tile being split
        tile_type_pkeys : List of int
            List of new tile_type_pkeys to be used after the tile split.
            The tile being split will become tile_type_pkeys[0], the next tile
            in split_direction will become tile_type_pkeys[1], etc.
        split_direction : Direction
            Which direction from tile should the split occur.
        split_map : Dict of (int, int) to int
            Mapping of site location (x, y) to tile_type_pkey indicies.
            This enables control over which sites go to which tiles based on
            their coordinate.

            min(split_map.values()) >= 0
            max(split_map.values()) < len(tile_type_pkeys)

        """
        sites = tile.sites
        tile.tile_type_pkey = self.empty_tile_type_pkey
        phy_tile_pkeys = set(tile.phy_tile_pkeys)
        new_tiles = []

        for idx, tile in enumerate(tile.walk_in_direction(split_direction)):
            assert tile.tile_type_pkey == self.empty_tile_type_pkey, (
                tile.tile_type_pkey
            )
            tile.phy_tile_pkeys = []

            new_tiles.append(tile)

            if idx + 1 >= len(tile_type_pkeys):
                break

        for tile, new_tile_type_pkey in zip(new_tiles, tile_type_pkeys):
            assert tile.tile_type_pkey == self.empty_tile_type_pkey

            tile.tile_type_pkey = new_tile_type_pkey
            tile.phy_tile_pkeys = list(
                set(tile.phy_tile_pkeys) | phy_tile_pkeys
            )
            tile.sites = []
            tile.split_sites = True

        for site in sites:
            site_idx = split_map[site.x, site.y]
            assert site_idx < len(tile_type_pkeys), (
                site, site_idx, tile_type_pkeys
            )
            new_tiles[site_idx].sites.append(site)

    def insert_empty(self, top, insert_in_direction):
        """ Insert empty row/colum.

        Insert a row/column of empty tiles from the tiles in the row/column specified
        by top_of_row/column tile.  The new empty tiles will have tile_type_pkey
        set to empty_tile_type_pkey, and have phy_tile_pkeys of the tile they
        were inserted from.

        Parameters
        ----------
        top_of_row/column : Tile object
            Tile at top of row/column adjcent to where new row/column should be
            inserted.
        insert_in_direction : Direction
            Direction to insert empty tiles, from perspective of the row/column
            specified by top_of_row/column.

        """
        # Verify that insert direction is not the same as zipper direction.
        next_dir = SPLIT_NEXT_DIRECTIONS[insert_in_direction]

        # Verify that top is in fact the top of the zipper
        assert OPPOSITE_DIRECTIONS[next_dir] not in top.neighboors

        empty_tiles = []
        for tile in top.walk_in_direction(next_dir):
            empty_tile = Tile(
                root_phy_tile_pkeys=[],
                phy_tile_pkeys=list(tile.phy_tile_pkeys),
                tile_type_pkey=self.empty_tile_type_pkey,
                sites=[]
            )
            empty_tiles.append(empty_tile)

            tile.insert_in_direction(empty_tile, insert_in_direction)

        for a, b in zip(empty_tiles, empty_tiles[1:]):
            a.link_neighboor_in_direction(b, next_dir)

        self.check_grid()

    def split_in_dir(
            self,
            top,
            tile_type_pkey,
            tile_type_pkeys,
            split_direction,
            split_map,
    ):
        """ Split row/column of tiles.

        Splits specified tile types into new row/column by first inserting any
        required empty row/column in the split direction, and then performing
        the split.

        Parameters
        ----------
        top_of_row/column : Tile object
            Tile at top of row/column where split should be performed.
        tile_type_pkey : Tile type to split.
        tile_type_pkeys : Refer to split_tile documentation.
        split_direction : Direction
            Direction to insert perform split.  New row/column will be inserted
            in that direction to accomidate the tile split.
        split_map : Dict of (int, int) to int
            Mapping of site location (x, y) to tile_type_pkey indicies.
            This enables control over which sites go to which tiles based on
            their coordinate.

        """
        next_dir = SPLIT_NEXT_DIRECTIONS[split_direction]

        # Find how many empty tiles are required to support the split
        num_to_insert = 0
        for tile in top.walk_in_direction(next_dir):
            if tile.tile_type_pkey != tile_type_pkey:
                continue

            for idx, tile_in_split in enumerate(
                    tile.walk_in_direction(split_direction)):
                if idx == 0:
                    continue
                else:
                    if tile_in_split.tile_type_pkey != self.empty_tile_type_pkey:
                        num_to_insert = max(num_to_insert, idx)

                    if idx + 1 >= len(tile_type_pkeys):
                        break

        for _ in range(num_to_insert):
            self.insert_empty(top, split_direction)

        for tile in top.walk_in_direction(next_dir):
            if tile.tile_type_pkey != tile_type_pkey:
                continue

            self.split_tile(tile, tile_type_pkeys, split_direction, split_map)

    def split_tile_type(
            self, tile_type_pkey, tile_type_pkeys, split_direction, split_map
    ):
        """ Split a specified tile type within grid.

        Splits specified tile types by finding each column that contains the
        relevant tile type, and spliting each column.

        Parameters
        ----------
        tile_type_pkey : Tile type to split.
        tile_type_pkeys : Refer to split_tile documentation.
        split_direction : Direction
            Direction to insert perform split.
        split_map : Dict of (int, int) to int
            Mapping of site location (x, y) to tile_type_pkey indicies.
            This enables control over which sites go to which tiles based on
            their coordinate.

        """
        tiles_seen = set()
        tiles = []
        tops_to_split = []

        next_dir = SPLIT_NEXT_DIRECTIONS[split_direction]

        for tile in self.items:
            if id(tile) in tiles_seen:
                continue

            if tile.tile_type_pkey == tile_type_pkey:
                # Found a row/column that needs to be split, walk to the bottom of
                # the row/column, then back to the top.
                for tile in tile.walk_in_direction(next_dir):
                    pass

                for tile in tile.walk_in_direction(
                        OPPOSITE_DIRECTIONS[next_dir]):
                    if id(tile) not in tiles_seen:
                        tiles_seen.add(id(tile))
                        if tile.tile_type_pkey == tile_type_pkey:
                            tiles.append(tile)

                tops_to_split.append(tile)

        for top in tops_to_split:
            self.split_in_dir(
                top, tile_type_pkey, tile_type_pkeys, split_direction,
                split_map
            )

    def merge_in_dir(self, tile, merge_direction):
        """ Merge tile in specified direction.

        Merging a tile causes the connects of that tile to be merged into
        the tile in the merge direction.  The tile that was merged will become
        empty.

        The original tile root_phy_tile_pkeys and phy_tile_pkeys will appear
        first.

        Parameters
        ----------
        tile : Tile
            Tile to merge
        merge_direction : Direction
            Direction to merge tiles.
        """
        assert merge_direction in tile.neighboors, (tile, merge_direction)

        merge_into = tile.neighboors[merge_direction]

        merge_into.root_phy_tile_pkeys.extend(tile.root_phy_tile_pkeys)
        merge_into.phy_tile_pkeys.extend(tile.phy_tile_pkeys)
        merge_into.sites.extend(tile.sites)

        tile.sites = list()
        tile.tile_type_pkey = self.empty_tile_type_pkey
        tile.root_phy_tile_pkeys = list()
        tile.phy_tile_pkeys = list()

    def merge_tile_type(self, tile_type_pkey, merge_direction):
        """ Merge tile types in specified direction.

        Parameters
        ----------
        tile_type_pkey : Tile type to split.
        merge_direction : Direction
            Direction to merge tiles.

        """
        for tile in self.items:
            if tile.tile_type_pkey == tile_type_pkey:
                self.merge_in_dir(tile, merge_direction)

    def output_grid(self):
        """ Convert grid back to coordinate lookup form.

        Returns
        -------
        grid_loc_map : Dict of 2 int tuple to Tile objects
            Output grid of Tile objects.

        """
        grid_loc_map = {}
        for x, tile in enumerate(self.origin.walk_in_direction(EAST)):
            for y, tile in enumerate(tile.walk_in_direction(SOUTH)):
                grid_loc_map[(x, y)] = tile

        check_grid_loc(grid_loc_map)

        return grid_loc_map

    def check_grid(self):
        """ Verifies that grid linked list model still represents valid grid.
        """
        self.output_grid()
