import ipaddress


def list_all_available_cidr(jnj_root_cidr_list, allocated_cidr_list, subnet_prefix):
    """
    Find all CIDRs of specified size from the provided top level CIDR list in the region

    Args:
        jnj_root_cidr_list: top-level CIDRs allocated to region
        allocated_cidr_list: CIDRs currently in use in region
        subnet_prefix: requested CIDR size

    Returns: locked CIDR
    """
    # Initialize result array
    available_cidr_list = []
    # Iterate through root level CIDRs
    for cidr in jnj_root_cidr_list:
        # Cast top-level CIDR string to network objet
        cidr = ipaddress.IPv4Network(cidr)
        # If top-level CIDR is smaller than requested CIDR, skip this top-level CIDR
        if int(cidr.prefixlen) > int(subnet_prefix):
            continue
        # Iterate through already allocated CIDRs
        allocated_cidr_in_master_list = [ipaddress.IPv4Network(cidr_block) for cidr_block in allocated_cidr_list if
                                         ipaddress.IPv4Network(cidr_block).overlaps(cidr)]
        # Divide the top-level CIDR into a CIDRs of the requested size
        cidr_subnets = list(cidr.subnets(new_prefix=int(subnet_prefix)))
        # Iterate through theoretical subnets and search for overlap
        for subnet in cidr_subnets:
            # Search for overlap with already allocated CIDRs
            subnet_conflict_flag = False
            for allocated_cidr in allocated_cidr_in_master_list:
                if subnet.overlaps(allocated_cidr):
                    subnet_conflict_flag = True
                    break
            # Found a conflict
            if subnet_conflict_flag:
                continue
            # This subnet has no conflicts, append to list of available subnets
            else:
                available_cidr_list.append(subnet.with_prefixlen)
    # Return results
    return available_cidr_list