#! /usr/bin/env python3

import threading

class Node(object):
  __num__ = 0
  __lock__ = threading.Lock()

  def __init__(self, name, *children):
    self.name = name
    self.nodes = [child for child in children]

    Node.__lock__.acquire()
    self.num = Node.__num__
    Node.__num__ += 1
    Node.__lock__.release()

    # the next attribute is used by the __next__() method
    self.next = 0

  def append(self, node):
    self.nodes.append(node)

  def __iter__(self):
    self.next = 0
    return self

  def __next__(self):
    if self.next >= len(self.nodes):
      raise StopIteration()

    node = self.nodes[self.next]
    self.next += 1
    return node

def tour(node, depth=0):
  if node is not None:
    print(f'{" "*(2*depth)}{node.name} ({node.num})')
    for child in node:
      tour(child, depth+1)

root = Node('root')
root.append(Node('one'))
root.append(Node('two'))
root.append(Node('three', Node('three-one'), Node('three-three')))
root.append(Node('four'))

root = Node('grandroot', root)

tour(root)
