# Velians BT question
class BTNode:
    """Generic binary tree node."""

    def __init__(self: 'BTNode', value: int) -> None:
        """initialize BTNode with value v"""
        self.value, self.left, self.right = value, None, None

    def __repr__(self: 'BTNode') -> str:
        """represent this BTNode as a string"""
        return ('BTNode(' + repr(self.value) + ', ' + repr(self.left) +
                ', ' + repr(self.right) + ')')

class LLNode:
    """doubly linked list node"""

    def __init__(self: 'LLNode', value: int) -> None:
        """initialize LLNode with value"""
        self.value, self.prev, self.next = value, None, None

    def __repr__(self: 'LLNode') -> str:
        """represent this LLNode as a string"""
        # why is this a terrible idea?
        return ('LLNode(' + repr(self.value) + ', ' +
                repr(self.prev) +', ' + repr(self.next) + ')')


def flatten(node: BTNode) -> (LLNode, LLNode):
    """return a pair consisting of head and tail of linked list
    containing flattened tree rooted at node.

    >>> tree = BTNode(5)
    >>> tree.left  = BTNode(4)
    >>> tree.right = BTNode(7)
    >>> tree.right.left = BTNode(6)
    >>> list_left, list_right = flatten(tree)
    >>> list_left.value
    4
    >>> list_left.next.value
    5
    >>> list_left.next.next.value
    6
    >>> list_left.next.next.next.value
    7
    >>> list_right.value
    7
    >>> list_right.prev.value
    6
    """
    if node:
        left_head, left_tail = flatten(node.left)
        right_head, right_tail = flatten(node.right)
        new_node = LLNode(node.value)
        new_node.prev, new_node.next = left_tail, right_head
        if left_tail:
            left_tail.next = new_node
        else:
            left_head = new_node # there is no left tree to traverse
        if right_tail:
            right_head.prev = new_node
        else:
            right_tail = new_node # no right tree to traverse
        return (left_head, right_tail)
    else:
        return (None, None)

if __name__ == '__main__':
    import doctest
    doctest.testmod()