#!/usr/bin/env python3
"""
Functions for dealing with groups of points.
"""

import math
import string
import sys

import enum
from collections import defaultdict
from collections import namedtuple

from ..asserts import assert_eq
from ..asserts import assert_type

from ..rr_graph import Position, P

_NamedPosition = namedtuple("NamedPosition", ["pos", "names"])


class NamedPosition(_NamedPosition):
    """Class to store a position and a set of names associated with it."""

    def __new__(cls, pos, names):
        assert_type(pos, Position)
        assert_type(names, list)
        for n in names:
            assert_type(n, str)
        return _NamedPosition.__new__(cls, pos, names)

    @property
    def x(self):
        return self.pos.x

    @property
    def y(self):
        return self.pos.y

    @property
    def first(self):
        assert len(self.names) > 0, self.names
        return self.names[0]

    def __str__(self):
        return "NP({},{},{})".format(
            self.pos.x,
            self.pos.y,
            ",".join(repr(n) for n in self.names),
        )

    def __repr__(self):
        return self.__str__()


def NP(x, y, *n):
    """Syntactic sugar for NamedPosition."""
    n = list(n)
    if not n:
        n = ["{}+{}".format(string.ascii_letters[x], string.ascii_letters[y])]
    return NamedPosition(P(x, y), n)


class StraightSegment(list):
    class Type(enum.Enum):
        """Category of straight segment

        Vertical - all points have same x value
        Horizontal - all point have same y value
        Stub - single point, no direction yet.
        """

        V = '|'
        V__doc__ = 'Vertical'

        H = '-'
        H__doc__ = 'Horizontal'

        S = 'o'
        S__doc__ = 'Stub'

        def __repr__(self):
            return 'StraightSegment.Type.' + self.name

    def __init__(self, direction, positions):
        list.__init__(self, positions)
        assert_type(direction, StraightSegment.Type)
        assert_type(positions, list)
        if direction == StraightSegment.Type.S:
            assert len(positions) == 1, (
                "Stubs must only have one position not {}".format(positions)
            )
        else:
            for p in positions:
                assert_type(p, (Position, NamedPosition))
                if direction == StraightSegment.Type.V:
                    assert_eq(p[0].x, p.x)
                elif direction == StraightSegment.Type.H:
                    assert_eq(p[0].y, p.y)
                else:
                    assert False, "Unknown direction {}".format(direction)
        self.direction = direction

    @property
    def d(self):
        return self.direction

    def __str__(self):
        return "{} {}".format(self.direction.value, list.__repr__(self))

    def __repr__(self):
        return "{}({}, {})".format(
            self.__class__.__name__,
            self.direction,
            list.__repr__(self),
        )

    def y_range(self):
        y_pos = [p.y for p in self]
        return min(y_pos), max(y_pos)

    def x_range(self):
        x_pos = [p.x for p in self]
        return min(x_pos), max(x_pos)

    def along(self, pos):
        """Return if position lies along segment"""
        assert len(self) > 0
        assert_type(pos, (NamedPosition, Position))

        if len(self) == 1:
            assert self.d == StraightSegment.Type.S, (self, pos)
            return (pos.x == self[0].x) or (pos.y == self[0].y)
        elif self.d == StraightSegment.Type.V:
            return pos.x == self[0].x
        elif self.d == StraightSegment.Type.H:
            return pos.y == self[0].y
        else:
            assert False, "Weird segment %s" % self

    def get_at(self, pos):
        for p in self:
            if p.x == pos.x and p.y == pos.y:
                return p
        raise ValueError("Nothing found at {} {}".format(pos, self))

    def has_at(self, pos):
        try:
            self.get_at(pos)
            return True
        except ValueError:
            return False

    def replace(self, pos):
        """Replace point at same x and y. Essentially updating the names.
        If no match is found, list remains unmodified and the function returns False.
        """
        for i, p in enumerate(self):
            if pos.x != p.x or pos.y != p.y:
                continue
            self[i] = pos
            return True
        return False

    def append(self, pos):
        """Add new position. Update direction if needed"""
        if len(self) > 0:
            if pos.x == self[0].x:
                direction = StraightSegment.Type.V
            elif pos.y == self[0].y:
                direction = StraightSegment.Type.H
        else:
            direction = self.direction

        if self.direction == StraightSegment.Type.S:
            assert len(self) <= 1, "Stub must have at most single point"
            self.direction = direction
        assert direction == self.direction, "Can't append in different direction {} {}".format(
            self.direction, direction
        )
        list.append(self, pos)

    def extend_to(self, pos):
        """Return point starting at Segment first position and extend for connection to pos"""
        pclass = self[0].pos.__class__
        if self.d == StraightSegment.Type.H:
            return pclass(pos.x, self[0].y)
        elif self.d == StraightSegment.Type.V:
            return pclass(self[0].x, pos.y)
        elif self.d == StraightSegment.Type.S:
            return pclass(self[0].x, pos.y)
            # assert pos.x == self[0].x or pos.y == self[0].y, (pos, self)
            # return pclass(*pos)
        assert self.d != StraightSegment.Type.S, self
        assert False, self

    @property
    def names(self):
        """Return list of all names of points along segment"""
        names = []
        for npos in self:
            names.extend(n for n in npos.names)
        return list(set(names))


def straight_longest(positions):
    """Get the largest straight section from a group of positions.

    Arguments:
        positions : [(Position, [str, ...]), ...]

    Returns:
        (StraightSegment([Position|NamedPosition, ...]), [Position|NamedPosition, ...])

    >>> s, r = straight_longest([P(1,0),])
    >>> print(str(s))
    o [P(x=1, y=0)]

    >>> s, r = straight_longest([
    ...         P(1,0),
    ... P(0,1), P(1,1), P(2, 1), P(3, 1),
    ... P(0,2), P(1,2), P(2, 2), P(3, 2),
    ...         P(1,3),
    ... ])
    >>> print(str(s))
    - [P(x=0, y=2), P(x=1, y=2), P(x=2, y=2), P(x=3, y=2)]
    >>> s, r = straight_longest(r)
    >>> print(str(s))
    - [P(x=0, y=1), P(x=1, y=1), P(x=2, y=1), P(x=3, y=1)]
    >>> s, r = straight_longest(r)
    >>> print(str(s))
    | [P(x=1, y=0), P(x=1, y=3)]
    >>> r
    []

    >>> s, r = straight_longest([
    ...         P(1,0),
    ... P(0,1), P(1,1), P(2, 1),
    ...         P(1,2),
    ... ])
    >>> print(str(s))
    - [P(x=0, y=1), P(x=1, y=1), P(x=2, y=1)]
    >>> s, r = straight_longest(r)
    >>> print(str(s))
    | [P(x=1, y=0), P(x=1, y=2)]
    >>> r
    []

    >>> s, r = straight_longest([
    ...         P(1,0),
    ... P(0,1),         P(10, 1),
    ...         P(1,5),
    ... ])
    >>> print(str(s))
    - [P(x=0, y=1), P(x=10, y=1)]
    >>> s, r = straight_longest(r)
    >>> print(str(s))
    | [P(x=1, y=0), P(x=1, y=5)]
    >>> r
    []

    >>> s, r = straight_longest([
    ... P(0,0), P(1,0),
    ... P(0,1),         P(2, 1),
    ... P(0,2), P(1,2),
    ... P(0,3), P(1,3), P(2, 3),
    ... P(0,4), P(1,4),
    ... P(0,5),         P(2, 5),
    ... P(0,6), P(1,6),
    ... ])
    >>> print(str(s))
    | [P(x=0, y=0), P(x=0, y=1), P(x=0, y=2), P(x=0, y=3), P(x=0, y=4), P(x=0, y=5), P(x=0, y=6)]
    >>> s, r = straight_longest(r)
    >>> print(str(s))
    | [P(x=1, y=0), P(x=1, y=2), P(x=1, y=3), P(x=1, y=4), P(x=1, y=6)]
    >>> s, r = straight_longest(r)
    >>> print(str(s))
    | [P(x=2, y=1), P(x=2, y=3), P(x=2, y=5)]
    >>> r
    []

    """
    assert_type(positions, list)

    # Count how frequently each x and y coordinate is found.
    coordinate_count = {
        'x': defaultdict(int),
        'y': defaultdict(int),
    }
    for pos in positions:
        assert_type(pos, (Position, NamedPosition))
        coordinate_count['x'][pos.x] += 1
        coordinate_count['y'][pos.y] += 1

    # If out the most common x and v coordinates
    x_val = list(sorted((c, x) for x, c in coordinate_count['x'].items()))
    y_val = list(sorted((c, y) for y, c in coordinate_count['y'].items()))

    # Work out the direction this segment will run
    if x_val[-1][0] > y_val[-1][0]:
        direction = StraightSegment.Type.V
    else:
        direction = StraightSegment.Type.H

    # Work out which positions are on this segment
    segment = StraightSegment(direction, [])
    not_in_segment = []
    if direction == StraightSegment.Type.V:
        x_pos = x_val[-1][1]
        for pos in positions:
            if pos.x != x_pos:
                not_in_segment.append(pos)
                continue
            segment.append(pos)
    elif direction == StraightSegment.Type.H:
        direction = "-"
        y_pos = y_val[-1][1]
        for pos in positions:
            if pos.y != y_pos:
                not_in_segment.append(pos)
                continue
            segment.append(pos)

    # Single length segments are "stubs"
    if len(segment) == 1:
        segment.direction = StraightSegment.Type.S

    return segment, not_in_segment


def print_segments(segs):
    for s in segs:
        print(s)


def print_conns(conns):
    for p, joins in sorted(conns.items()):
        for (aname, bname) in joins:
            print("{}x{} {}<->{}".format(p.x, p.y, aname, bname))


def decompose_into_straight_lines(positions):
    """
    Takes a network and converts it to a list of straight segments.


    Arguments:
        positions : [(Position, [str, ...]), ...]

    >>> # Single element
    >>> pos = [NP(1,0),]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> for s in segs:
    ...     print(s)
    o [NP(1,0,'b+a')]

    >>> # Single horizontal line
    >>> pos = [NP(1,0), NP(2,0)]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> for s in segs:
    ...     print(s)
    - [NP(1,0,'b+a'), NP(2,0,'c+a')]

    >>> # Single vertical line
    >>> pos = [NP(1,2), NP(1,3)]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> for s in segs:
    ...     print(s)
    | [NP(1,2,'b+c'), NP(1,3,'b+d')]

    >>> # Cross shape
    >>> pos = [
    ...           NP(1,0),
    ...  NP(0,1), NP(1,1), NP(2, 1),
    ...           NP(1,2),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    - [NP(0,1,'a+b'), NP(1,1,'b+b'), NP(2,1,'c+b')]
    | [NP(1,0,'b+a'), NP(1,1,'b+b_x'), NP(1,2,'b+c')]
    >>> print_conns(conns)
    1x1 b+b<->b+b_x

    >>> # Cross with two horizontal bars
    >>> pos = [
    ...           NP(1,0),
    ...  NP(0,1), NP(1,1), NP(2, 1), NP(3, 1),
    ...  NP(0,2), NP(1,2), NP(2, 2), NP(3, 2),
    ...           NP(1,3),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    - [NP(0,1,'a+b'), NP(1,1,'b+b'), NP(2,1,'c+b'), NP(3,1,'d+b')]
    - [NP(0,2,'a+c'), NP(1,2,'b+c'), NP(2,2,'c+c'), NP(3,2,'d+c')]
    | [NP(1,0,'b+a'), NP(1,1,'b+b_x'), NP(1,2,'b+c_x'), NP(1,3,'b+d')]
    >>> print_conns(conns)
    1x1 b+b<->b+b_x
    1x2 b+c<->b+c_x

    >>> # Cross with unequal horizontal bars
    >>> pos = [
    ...           NP(1,0),
    ...  NP(0,1), NP(1,1), NP(2, 1), NP(3, 1),
    ...  NP(0,2), NP(1,2), NP(2, 2),
    ...           NP(1,3),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    - [NP(0,1,'a+b'), NP(1,1,'b+b'), NP(2,1,'c+b'), NP(3,1,'d+b')]
    - [NP(0,2,'a+c'), NP(1,2,'b+c'), NP(2,2,'c+c')]
    | [NP(1,0,'b+a'), NP(1,1,'b+b_x'), NP(1,2,'b+c_x'), NP(1,3,'b+d')]
    >>> print_conns(conns)
    1x1 b+b<->b+b_x
    1x2 b+c<->b+c_x

    >>> # FIXME: Cross with missing middle
    >>> pos = [
    ...           NP(1,0),
    ...  NP(0,1),          NP(10, 1),
    ...           NP(1,5),
    ... ]
    >>> try:
    ...     conns, segs = decompose_into_straight_lines(pos)
    ... except AssertionError:
    ...     pass

    >>> # 3 straight lines
    >>> pos = [
    ...  NP(0,0), NP(1,0),
    ...  NP(0,1),          NP(2,1),
    ...  NP(0,2), NP(1,2),
    ...  NP(0,3), NP(1,3), NP(2,3),
    ...  NP(0,4), NP(1,4),
    ...  NP(0,5),          NP(2,5),
    ...  NP(0,6), NP(1,6),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    | [NP(0,0,'a+a'), NP(0,1,'a+b'), NP(0,2,'a+c'), NP(0,3,'a+d'), NP(0,4,'a+e'), NP(0,5,'a+f'), NP(0,6,'a+g')]
    - [NP(0,3,'a+d_x'), NP(1,3,'b+d_x'), NP(2,3,'c+d_x')]
    | [NP(1,0,'b+a'), NP(1,2,'b+c'), NP(1,3,'b+d'), NP(1,4,'b+e'), NP(1,6,'b+g')]
    | [NP(2,1,'c+b'), NP(2,3,'c+d'), NP(2,5,'c+f')]
    >>> print_conns(conns)
    0x3 a+d<->a+d_x
    1x3 b+d<->b+d_x
    2x3 c+d<->c+d_x

    >>> # H shaped
    >>> pos = [
    ...  NP(0,0),          NP(2,0),
    ...  NP(0,1),          NP(2,1),
    ...  NP(0,2),          NP(2,2),
    ...  NP(0,3), NP(1,3), NP(2,3),
    ...  NP(0,4),          NP(2,4),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    | [NP(0,0,'a+a'), NP(0,1,'a+b'), NP(0,2,'a+c'), NP(0,3,'a+d'), NP(0,4,'a+e')]
    - [NP(0,3,'a+d_x'), NP(1,3,'b+d'), NP(2,3,'c+d_x')]
    | [NP(2,0,'c+a'), NP(2,1,'c+b'), NP(2,2,'c+c'), NP(2,3,'c+d'), NP(2,4,'c+e')]
    >>> print_conns(conns)
    0x3 a+d<->a+d_x
    2x3 c+d<->c+d_x

    >>> # Corner shape
    >>> pos = [
    ...  NP(0,1,'io_0/D_IN_0'), NP(1,1,'neigh_op_lft_0','neigh_op_lft_4'),
    ...                         NP(1,2,'neigh_op_bnl_0','neigh_op_bnl_4'),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    - [NP(0,1,'io_0/D_IN_0'), NP(1,1,'neigh_op_lft_0','neigh_op_lft_4')]
    | [NP(1,1,'neigh_op_lft_0_x'), NP(1,2,'neigh_op_bnl_0','neigh_op_bnl_4')]
    >>> print_conns(conns)
    1x1 neigh_op_lft_0<->neigh_op_lft_0_x

    >>> # Going around corners
    >>> pos = [
    ...                            NP(1,0,'span4_horz_r_4'), NP(2,0,'span4_horz_r_8'), NP(3,0,'span4_horz_r_12'), NP(4,0,'span4_horz_l_12'),
    ...  NP(0,1,'span4_vert_b_0'),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    - [NP(0,0,'span4_horz_r_4_to_span4_vert_b_0'), NP(1,0,'span4_horz_r_4'), NP(2,0,'span4_horz_r_8'), NP(3,0,'span4_horz_r_12'), NP(4,0,'span4_horz_l_12')]
    | [NP(0,0,'span4_horz_r_4_to_span4_vert_b_0_x'), NP(0,1,'span4_vert_b_0')]
    >>> print_conns(conns)
    0x0 span4_horz_r_4_to_span4_vert_b_0<->span4_horz_r_4_to_span4_vert_b_0_x

    >>> pos = [
    ...                            NP(1,0,'span4_horz_r_4'), NP(2,0,'span4_horz_r_8'), NP(3,0,'span4_horz_r_12'),
    ...  NP(0,1,'span4_vert_b_0'),
    ...  NP(0,2,'span4_vert_b_0'),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    - [NP(0,0,'span4_horz_r_4_to_span4_vert_b_0'), NP(1,0,'span4_horz_r_4'), NP(2,0,'span4_horz_r_8'), NP(3,0,'span4_horz_r_12')]
    | [NP(0,0,'span4_horz_r_4_to_span4_vert_b_0_x'), NP(0,1,'span4_vert_b_0'), NP(0,2,'span4_vert_b_0')]
    >>> print_conns(conns)
    0x0 span4_horz_r_4_to_span4_vert_b_0<->span4_horz_r_4_to_span4_vert_b_0_x

    >>> pos = [
    ...  NP(10,0,'span4_horz_r_4'), NP(12,0,'span4_horz_r_8'), NP(13,0,'span4_horz_r_12'),
    ...                                                                                    NP(14,1,'span4_vert_b_0'),
    ...                                                                                    NP(14,2,'span4_vert_b_0'),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    - [NP(10,0,'span4_horz_r_4'), NP(12,0,'span4_horz_r_8'), NP(13,0,'span4_horz_r_12'), NP(14,0,'span4_horz_r_12_to_span4_vert_b_0')]
    | [NP(14,0,'span4_horz_r_12_to_span4_vert_b_0_x'), NP(14,1,'span4_vert_b_0'), NP(14,2,'span4_vert_b_0')]
    >>> print_conns(conns)
    14x0 span4_horz_r_12_to_span4_vert_b_0<->span4_horz_r_12_to_span4_vert_b_0_x

    >>> # FIXME: This is a bit weird
    >>> # Make sure NP(1,2) isn't in the output...
    >>> pos = [
    ... NP(0,0),          NP(2,0),
    ... NP(0,1), NP(1,1), NP(2,1),
    ... NP(0,2),          NP(2,2),
    ... NP(0,3), NP(1,3), NP(2,3),
    ... NP(0,4),          NP(2,4),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    | [NP(0,0,'a+a'), NP(0,1,'a+b'), NP(0,2,'a+c'), NP(0,3,'a+d'), NP(0,4,'a+e')]
    - [NP(0,3,'a+d_x'), NP(1,3,'b+d_x'), NP(2,3,'c+d_x')]
    | [NP(1,1,'b+b'), NP(1,3,'b+d')]
    | [NP(2,0,'c+a'), NP(2,1,'c+b'), NP(2,2,'c+c'), NP(2,3,'c+d'), NP(2,4,'c+e')]
    >>> print_conns(conns)
    0x3 a+d<->a+d_x
    1x3 b+d<->b+d_x
    2x3 c+d<->c+d_x

    >>> # FIXME: This is weird?
    >>> pos = [
    ...  NP(0,16,'span4_vert_t_12'),
    ...                              NP(1,17,'span4_horz_l_12'),
    ... ]
    >>> conns, segs = decompose_into_straight_lines(pos)
    >>> print_segments(segs)
    - [NP(0,16,'span4_vert_t_12'), NP(1,16,'span4_horz_l_12_to_span4_vert_t_12_x')]
    | [NP(1,16,'span4_horz_l_12_to_span4_vert_t_12'), NP(1,17,'span4_horz_l_12')]
    >>> print_conns(conns)
    1x16 span4_horz_l_12_to_span4_vert_t_12<->span4_horz_l_12_to_span4_vert_t_12_x

    """ # noqa: 501
    assert len(positions) > 0, positions
    for pos in positions:
        assert_type(pos, NamedPosition)

    npclass = positions[0].__class__
    pclass = positions[0].pos.__class__

    # position_used_by[position] = (NamedPosition, StraightSegment)
    position_used_by = {}
    segments = {
        '|': [],
        '-': [],
        'o': [],
        'ALL': [],
    }
    # connections[position] = (namea, nameb)
    connections = defaultdict(list)

    def add_segment(s, is_spine=False):
        assert len(s) > 0, (s, is_spine)
        assert_type(s, StraightSegment)
        for np in s:
            assert_type(np, NamedPosition)
            if not is_spine:
                assert np.pos not in position_used_by, (
                    np.pos, s, position_used_by[np.pos]
                )
                position_used_by[np.pos] = (np, s)

        for p, (other_p, other_s) in position_used_by.items():
            assert p.x == other_p.x, (p, other_p)
            assert p.y == other_p.y, (p, other_p)
            if s is other_s:
                continue

            if not s.along(p):
                continue

            assert p not in connections, (p, connections)

            current_name = other_p.names[0]
            new_name = current_name + '_x'

            connection_p = npclass(p, [new_name])
            if is_spine:
                s.replace(connection_p)
            else:
                s.append(connection_p)
            connections[p].append((current_name, new_name))
        s.sort()
        # print(s)
        segments['ALL'].append(s)
        segments[s.d.value].append(s)

    # Convert the positions into straight lines.
    remaining = list(positions)
    while len(remaining) > 0:
        assert_type(remaining, list)
        straight_segment, remaining = straight_longest(remaining)
        add_segment(straight_segment)

    if len(segments['ALL']) == 1:
        assert len(connections) == 0, (segments, connections)
        return connections, segments['ALL']

    # FIXME: Hack for dealing with the corner case
    if len(segments['ALL']) == 2 and len(connections) == 0:
        longest = segments['ALL'][0]
        other = []
        for seg in segments['ALL'][1:]:
            if len(longest) < len(seg):
                longest, seg = seg, longest
            other.append(seg)

        # assert len(other) == 1, (longest, other)
        # assert len(longest) > 1, (longest, other)
        pointa, pointb = straight_closet(longest, other[0])
        corner_point = longest.extend_to(pointb)
        corner_name = "{}_to_{}".format(pointa.names[0], pointb.names[0])
        longest.append(npclass(corner_point, [corner_name]))
        longest.sort()
        other[0].append(npclass(corner_point, [corner_name + "_x"]))
        other[0].sort()
        connections[corner_point].append((corner_name, corner_name + "_x"))
    """
    # FIXME: Check all the segments are connected together
    for_checking = list(segments['ALL'])
    connected = [for_checking.pop(0)]
    while len(for_checking) > 0:
        point = None
        for seg1 in for_checking:
            for seg2 in connected:
                test_point = common_point(seg1, seg2)
                if test_point is not None:
                    point = test_point
                    connected.append(seg2)
                    break
        if point is not None:
            for_checking.remove(connected[-1])
        else:
            assert False, (for_checking, connected)
    """

    # Check connections
    # If they are all vertical or horizontal, we need to create a spine.
    if len(connections) == 0 and len(segments['-']) > 0:
        assert len(segments['|']) == 0
        for seg in segments['o']:
            seg.direction = StraightSegment.Type.H
            segments['-'].append(seg)

        x_pos = defaultdict(int)
        for seg in segments['-']:
            assert len(seg) > 0, seg
            for p in seg:
                x_pos[p.x] += 1

        x = list(sorted((m, x) for x, m in x_pos.items()))[-1][-1]

        spine = StraightSegment(StraightSegment.Type.V, [])
        for seg in segments['-']:
            p = pclass(x, seg.y_range()[0])
            spine.append(npclass(p, names=[seg.get_at(p).first]))
        add_segment(spine, True)

    elif len(connections) == 0 and len(segments['|']) > 0:
        assert len(segments['-']) == 0
        for seg in segments['o']:
            seg.direction = StraightSegment.Type.V
            segments['|'].append(seg)

        y_pos = defaultdict(int)
        for seg in segments['|']:
            assert len(seg) > 0, seg
            for p in seg:
                y_pos[p.y] += 1

        y = list(sorted((m, y) for y, m in y_pos.items()))[-1][-1]

        spine = StraightSegment(StraightSegment.Type.H, [])
        for seg in segments['|']:
            assert len(seg) > 0, seg
            p = pclass(seg.x_range()[0], y)
            spine.append(npclass(p, names=[seg.get_at(p).first]))
        add_segment(spine, True)

    segments['ALL'].sort()
    return connections, segments['ALL']


def straight_ends(positions):
    """Get the ends of a straight line.

    >>> straight_ends([P(0,1), P(1,1)])
    (P(x=0, y=1), P(x=1, y=1))

    >>> straight_ends([P(0,1), P(1,1), P(2,1)])
    (P(x=0, y=1), P(x=2, y=1))

    >>> straight_ends([P(1,0), P(1,1), P(1,2)])
    (P(x=1, y=0), P(x=1, y=2))

    >>> straight_ends([P(1,1), P(1,1)])
    (P(x=1, y=1), P(x=1, y=1))

    >>> # FIXME: Is this the correct behaviour?
    >>> straight_ends([P(1,1), P(1,4)])
    (P(x=1, y=1), P(x=1, y=4))

    >>> straight_ends([P(0,0), P(1,1)])
    Traceback (most recent call last):
      ...
    TypeError: Not straight x:{0, 1} y:{0, 1}
    >>> straight_ends([P(0,0), P(1,1), P(0,2)])
    Traceback (most recent call last):
      ...
    TypeError: Not straight x:{0, 1} y:{0, 1, 2}

    """
    pclass = positions[0].__class__

    x_pos = set(p.x for p in positions)
    y_pos = set(p.y for p in positions)

    if len(x_pos) > 1:
        if len(y_pos) != 1:
            raise TypeError("Not straight x:{} y:{}".format(x_pos, y_pos))
    if len(y_pos) > 1:
        if len(x_pos) != 1:
            raise TypeError("Not straight x:{} y:{}".format(x_pos, y_pos))

    start = pclass(min(x_pos), min(y_pos))
    end = pclass(max(x_pos), max(y_pos))

    assert start.x == end.x or start.y == end.y, "{} {}".format(start, end)

    return start, end


def distance(p1, p2):
    return math.sqrt((p2.x - p1.x)**2 + (p2.y - p1.y)**2)


def straight_closet(line1, line2):
    """

    # >>> straight_intersection((P(0, 0), P(0, 10)), (P(0, 0), P(10, 0)))
    # P(x=0, y=0)
    # >>> straight_intersection((P(10, 0), P(10, 10)), (P(0, 0), P(10, 0)))
    # P(x=10, y=0)
    # >>> straight_intersection((P(5, 0), P(5, 10)), (P(0, 0), P(10, 0)))
    # P(x=5, y=0)
    # >>> straight_intersection((P(0, 5), P(10, 5)), (P(5, 0), P(5, 10)))
    # P(x=5, y=5)

    """
    min_d = sys.maxsize
    pa, pb = None, None

    for p1 in line1:
        for p2 in line2:
            d = distance(p1, p2)
            if d < min_d:
                pa, pb = p1, p2
                min_d = d

    assert pa is not None, "{} {}".format(line1, line2)
    assert pb is not None, "{} {}".format(line1, line2)
    return pa, pb


class Point(object):
    def __init__(self, coord):
        self.x, self.y = coord
        self.tracks = 0

    def __repr__(self):
        return 'Point(coord=({},{}),tracks={})'.format(
            self.x, self.y, repr(self.tracks)
        )


class Track(object):
    def __init__(self, dim, tracks=None, other_tracks=None, points=[]):
        self.dim = dim

        self.points = []
        self.tracks = tracks
        self.other_tracks = other_tracks
        for p in points:
            self.add_point(p)

    def add_point(self, p):
        self.points.append(p)
        p.tracks += 1

    def __repr__(self):
        return 'Track(dim={},points={})'.format(
            repr(self.dim), repr(self.points)
        )


def decompose_points_into_tracks(
        points, grid_width=None, grid_height=None, right_only=False
):
    """ This function takes a bag of points and returns a set of x lines and
        y lines that cover all points, and all lines touch each other.

    This is the first step to forming VPR tracks from points.  VPR tracks have
    limited length, whereas this function returns lines of infinite length.

    Args:
        points: List of (x, y) tuples that are points to be connected into the
            the track
        grid_width (int): Optional maximum x dimension
        grid_height (int): Optional maximum y dimension
        right_only (bool): Assume that points are only available via pins on
            the right.  Some arches restrict pins to the right side only.

    >>> # Single element
    >>> pos = [(1,0)]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = []
    y = [0]

    >>> # Single horizontal line
    >>> pos = [(1,0), (2,0)]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = []
    y = [0]

    >>> # Single vertical line
    >>> pos = [(1,2), (1,3)]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [1]
    y = []

    >>> # Cross shape
    >>> pos = [
    ...         (2,1),
    ...  (1,2), (2,2), (3, 2),
    ...         (2,3),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [2]
    y = [2]

    >>> # Cross shape at edge
    >>> pos = [
    ...         (1,0),
    ...  (0,1), (1,1), (2, 1),
    ...         (1,2),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = [0]

    >>> # Cross with two horizontal bars
    >>> pos = [
    ...         (1,0),
    ...  (0,1), (1,1), (2, 1), (3, 1),
    ...  (0,2), (1,2), (2, 2), (3, 2),
    ...         (1,3),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = [0, 1]

    >>> # Cross with unequal horizontal bars
    >>> pos = [
    ...         (1,0),
    ...  (0,1), (1,1), (2, 1), (3, 1),
    ...  (0,2), (1,2), (2, 2),
    ...         (1,3),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = [0, 1]

    >>> pos = [
    ...           (1,0),
    ...  (0,1),          (10, 1),
    ...           (1,5),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = [0]

    >>> # 3 straight lines
    >>> pos = [
    ...         (1,0),
    ...  (0,1),          (2,1),
    ...  (0,2), (1,2),
    ...  (0,3), (1,3),   (2,3),
    ...  (0,4), (1,4),
    ...  (0,5),          (2,5),
    ...  (0,6), (1,6),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = [0, 3, 5]

    >>> # H shaped
    >>> pos = [
    ...                (2,0),
    ...  (0,1),        (2,1),
    ...  (0,2),        (2,2),
    ...  (0,3), (1,3), (2,3),
    ...  (0,4),        (2,4),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = [0, 2, 3]

    >>> # H shaped
    >>> pos = [
    ...  (1,1),        (3,1),
    ...  (1,2),        (3,2),
    ...  (1,3),        (3,3),
    ...  (1,4), (2,4), (3,4),
    ...  (1,5),        (3,5),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [1, 2]
    y = [4]

    >>> # Corner shape
    >>> pos = [
    ...  (0,1), (1,1),
    ...                         (1,2)
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = []

    >>> # Going around corners
    >>> pos = [
    ...         (1,0), (2,0), (3,0), (4,0),
    ...  (0,1),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = [0]

    >>> pos = [
    ...                            (1,0), (2,0), (3,0),
    ...  (0,1),
    ...  (0,2),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = [0]

    >>> pos = [
    ...  (10,0), (12,0), (13,0),
    ...                          (14,1),
    ...                          (14,2),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [14]
    y = [0]

    >>> # Make sure (1,2) isn't in the output...
    >>> pos = [
    ...               (2,0),
    ... (0,1), (1,1), (2,1),
    ... (0,2),        (2,2),
    ... (0,3), (1,3), (2,3),
    ... (0,4),        (2,4),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = [0, 2, 3]

    >>> pos = [
    ...  (0,16),
    ...          (1,17),
    ... ]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [0]
    y = []

    >>> pos = [
    ... (68,48), (69,48),
    ... (68,49), (69,49),
    ...          (69,50),
    ...          (69,51),
    ...          (69,52),
    ...          (69,53), (70,53), (71,53), (72,53)]
    >>> ret = decompose_points_into_tracks(pos)
    >>> print_tracks(ret)
    x = [68]
    y = [52]

    """

    xs, ys = zip(*points)

    x_min = max(0, min(xs) - 1)
    x_max = max(xs)
    if grid_width is not None:
        x_max = min(x_max, grid_width - 2)

    y_min = max(0, min(ys) - 1)
    y_max = max(ys)
    if grid_height is not None:
        y_max = min(y_max, grid_height - 2)

    points = [Point(p) for p in points]
    x_tracks = {}
    y_tracks = {}

    for x in range(x_min, x_max + 1):
        x_tracks[x] = Track(dim=x, tracks=x_tracks, other_tracks=y_tracks)
    for y in range(y_min, y_max + 1):
        y_tracks[y] = Track(dim=y, tracks=y_tracks, other_tracks=x_tracks)

    def on_x_track(p):
        # x tracks extend from 1 to grid_height - 1
        if p.y <= 0:
            return False

        if grid_height is not None and p.y >= grid_height - 2:
            return False

        return True

    def on_y_track(p):
        # y tracks extend from 1 to grid_width - 1
        if p.x <= 0:
            return False

        if grid_width is not None and p.x >= grid_width - 2:
            return False

        return True

    def is_corner_point(p):
        if p.x == 0 and p.y == 0:
            return True

        if grid_width is not None:
            assert grid_height is not None
            if p.x == grid_width - 1 and p.y == 0:
                return True

            if p.x == 0 and p.y == grid_height - 1:
                return True

            if p.x == grid_width - 1 and p.y == grid_height - 1:
                return True

        return False

    for p in points:
        # No points in corner
        assert not is_corner_point(p), p

        if on_x_track(p) and p.x in x_tracks:
            # The x-1 connection is for left pins.
            if p.x > 0 and not right_only:
                x_tracks[p.x - 1].add_point(p)
            x_tracks[p.x].add_point(p)

        # If all pins are on the right, then the y_tracks are used for cross
        # bar only, and points are not connected.
        if on_y_track(p) and not right_only and p.y in y_tracks:
            if p.y > 0:
                y_tracks[p.y - 1].add_point(p)
            y_tracks[p.y].add_point(p)

    def try_remove_track(track):
        assert track.dim in track.tracks

        for point in track.tracks[track.dim].points:
            if point.tracks <= 1:
                return False

        # If there is more than 1 other track, cannot have zero of this track.
        if len(track.tracks) <= 1 and len(track.other_tracks) > 1:
            return False

        for point in track.tracks[track.dim].points:
            point.tracks -= 1

        del track.tracks[track.dim]

        return True

    # Attempt to remove tracks, starting with the track with the smallest
    # number of connections.
    while len(x_tracks) > 0 and len(y_tracks) > 0:
        x_track = min(x_tracks.values(), key=lambda key: len(key.points))
        y_track = min(y_tracks.values(), key=lambda key: len(key.points))

        if len(x_track.points) < len(y_track.points):
            if not try_remove_track(x_track):
                if not try_remove_track(y_track):
                    break
        else:
            if not try_remove_track(y_track):
                if not try_remove_track(x_track):
                    break

    # Walk each dimension, attempting to removing excess lines from the line
    # with the smallest number of points.
    while len(x_tracks) > 0:
        x_track = min(x_tracks.values(), key=lambda key: len(key.points))
        if not try_remove_track(x_track):
            break

    while len(y_tracks) > 0:
        y_track = min(y_tracks.values(), key=lambda key: len(key.points))
        if not try_remove_track(y_track):
            break

    # Walk each dimension, attempting to removing excess lines from any line,
    # starting with the smallest.
    while True:
        for x_track in sorted(x_tracks.values(),
                              key=lambda key: len(key.points)):
            if try_remove_track(x_track):
                continue
        for y_track in sorted(y_tracks.values(),
                              key=lambda key: len(key.points)):
            if try_remove_track(y_track):
                continue
        break

    # Sanity check results
    for p in points:
        on_a_track = False
        if on_x_track(p):
            if p.x > 0:
                on_a_track = on_a_track or p.x - 1 in x_tracks

            on_a_track = on_a_track or p.x in x_tracks

        if on_y_track(p):
            if p.y > 0:
                on_a_track = on_a_track or p.y - 1 in y_tracks

            on_a_track = on_a_track or p.y in y_tracks

        assert on_a_track, p

    return list(x_tracks.keys()), list(y_tracks.keys())


def print_tracks(ret):
    x_tracks, y_tracks = ret

    print('x = {}'.format(x_tracks))
    print('y = {}'.format(y_tracks))
