# Path: autonetkit/design/utils/filters.py
# def filter_nodes(topology: 'Topology', **kwargs) -> List['Node']:
# def routers(topology: 'Topology') -> List['Node']:
# def switches(topology: 'Topology') -> List['Node']:
# def hosts(topology: 'Topology') -> List['Node']:
# def broadcast_domains(topology) -> List['Node']:
# def physical_ports(node: 'Node') -> List['Port']:
# def find_node_by_label(topology: 'Topology', label) -> 'Node':
# 
# Path: autonetkit/design/utils/general.py
# def group_by(nodes: typing.List['Node'], key: str) -> typing.Dict[str, typing.List['Node']]:
#     """
# 
#     @param nodes:
#     @param key:
#     @return:
#     """
#     result = defaultdict(list)
#     for node in nodes:
#         result[node.get(key)].append(node)
# 
#     return dict(result)
# 
# Path: autonetkit/network_model/types.py
# LAYER3_DEVICES = {DeviceType.ROUTER, DeviceType.HOST}


import ipaddress
from collections import defaultdict
from autonetkit.design.utils import filters
from autonetkit.design.utils.general import group_by
from autonetkit.network_model.types import LAYER3_DEVICES
    loopback_block = ipaddress.IPv4Network("172.16.0.0/16")
    loopback_subnets = loopback_block.subnets(new_prefix=24)
    grouped_l3 = group_by(layer3_nodes, "asn")

    allocated_loopbacks = defaultdict(list)

    for asn, nodes in grouped_l3.items():
        # can repeat the loopbacks in each asn
        subnet = next(loopback_subnets)
        allocated_loopbacks[asn].append(subnet)
        host_ips = subnet.hosts()
        for node in nodes:
            host_ip = next(host_ips)
            lo0 = node.loopback_zero()
            lo0.set("ip", host_ip)
            # also map onto node for debugging/vis

    topology.set("loopbacks_by_asn", allocated_loopbacks)


def assign_bc_subnets(topology):
    """

    @param topology:
    """
    # the network to use to address end hosts and for inter-domain connections
    allocated_blocks = defaultdict(list)
    global_advertise_network = ipaddress.IPv4Network("10.0.0.0/8")
    global_subnets = global_advertise_network.subnets(new_prefix=16)
    bc_nodes = filters.broadcast_domains(topology)

# Path: autonetkit/design/utils/filters.py
# def filter_nodes(topology: 'Topology', **kwargs) -> List['Node']:
# def routers(topology: 'Topology') -> List['Node']:
# def switches(topology: 'Topology') -> List['Node']:
# def hosts(topology: 'Topology') -> List['Node']:
# def broadcast_domains(topology) -> List['Node']:
# def physical_ports(node: 'Node') -> List['Port']:
# def find_node_by_label(topology: 'Topology', label) -> 'Node':
# 
# Path: autonetkit/design/utils/general.py
# def group_by(nodes: typing.List['Node'], key: str) -> typing.Dict[str, typing.List['Node']]:
#     """
# 
#     @param nodes:
#     @param key:
#     @return:
#     """
#     result = defaultdict(list)
#     for node in nodes:
#         result[node.get(key)].append(node)
# 
#     return dict(result)
# 
# Path: autonetkit/network_model/types.py
# LAYER3_DEVICES = {DeviceType.ROUTER, DeviceType.HOST}


# Path: autonetkit/design/ip_addressing/ipv4.py
import ipaddress
from collections import defaultdict
from autonetkit.design.utils import filters
from autonetkit.design.utils.general import group_by
from autonetkit.network_model.types import LAYER3_DEVICES

    loopback_block = ipaddress.IPv4Network("172.16.0.0/16")
    loopback_subnets = loopback_block.subnets(new_prefix=24)
    grouped_l3 = group_by(layer3_nodes, "asn")

    allocated_loopbacks = defaultdict(list)

    for asn, nodes in grouped_l3.items():
        # can repeat the loopbacks in each asn
        subnet = next(loopback_subnets)
        allocated_loopbacks[asn].append(subnet)
        host_ips = subnet.hosts()
        for node in nodes:
            host_ip = next(host_ips)
            lo0 = node.loopback_zero()
            lo0.set("ip", host_ip)
            # also map onto node for debugging/vis

    topology.set("loopbacks_by_asn", allocated_loopbacks)


def assign_bc_subnets(topology):
    """

    @param topology:
    """
    # the network to use to address end hosts and for inter-domain connections
    allocated_blocks = defaultdict(list)
    global_advertise_network = ipaddress.IPv4Network("10.0.0.0/8")
    global_subnets = global_advertise_network.subnets(new_prefix=16)
    bc_nodes = filters.broadcast_domains(topology)

    grouped_bc = group_by(bc_nodes, "asn")