from typing import Set


def print_calltree(calldict: dict):
    """Print a space-indented recursive tree.

    An asterisk after a name indicates the function has already been traversed.
    """
    print('[+] Printing call tree with %d functions:' % len(calldict))
    # It looks nicer to start from obvious entry points
    default_roots = ['WinMain', 'wWinMain', 'main', 'wmain', '_main', '_start']
    root = None
    for root in default_roots:
        if root in calldict:
            break

    def recursive_print_node(cur_node: str, tree: dict, level: int, seen: set) -> Set[str]:
        indent = '    '
        if cur_node in seen:
            print('%s%s*' % (indent * level, cur_node))
            return seen
        print('%s%s' % (indent * level, cur_node))
        seen.add(cur_node)
        children = tree.get(cur_node, [])
        for child_node in sorted(children):
            child_saw = recursive_print_node(child_node, tree, level + 1, seen)
            seen.update(child_saw)
        return seen

    seen: Set[str] = set()
    while True:
        keys_left = calldict.keys() - seen
        if keys_left == set():
            break
        if root is None:
            # pick remaining node with most immediate children
            root = sorted(keys_left, key=lambda k: len(calldict[k]), reverse=True)[0]
        nodes_traversed = recursive_print_node(root, calldict, 0, seen)
        seen.update(nodes_traversed)
        root = None