# Path: oppy/path/util.py
# def nodeUsableWithOther(desc1, status_entry1, desc2, status_entry2):
# def selectWeightedNode(weighted_nodes):
# def getWeightedNodes(nodes, weights):
# def getPositionWeights(nodes, cons_rel_stats, position, bw_weights,
#                        bwweightscale):
# def getBwweight(flags, position, bw_weights):
# def inSameFamily(desc1, status_entry1, desc2, status_entry2):
# def inSame16Subnet(status_entry1, status_entry2):
# 
# Path: oppy/path/exceptions.py
# class NoUsableGuardsException(Exception):
#     pass
# 
# class PathSelectionFailedException(Exception):
#     pass


import random
from collections import namedtuple
from twisted.internet import defer
from stem import Flag
from oppy.path import util as path_util
from oppy.path.exceptions import (
    NoUsableGuardsException,
    PathSelectionFailedException,
)


def selectExitNode(bw_weights, bwweightscale, cons_rel_stats, descriptors,
                   fast, stable, internal, port):
    exits = filterExits(cons_rel_stats, descriptors, fast, stable, internal,
                        port)

    if len(exits) == 0:
        raise ValueError("No usable exit nodes for requested path.")

    if len(exits) == 1:
        return exits[0]

    weight_pos = 'm' if internal is True else 'e'
    weights = path_util.getPositionWeights(exits, cons_rel_stats, weight_pos,
                                           bw_weights, bwweightscale)
    weighted_exits = path_util.getWeightedNodes(exits, weights)

    return path_util.selectWeightedNode(weighted_exits)


def selectGuardNode(cons_rel_stats, descriptors, guards, fast, stable,
                    exit_desc, exit_status_entry):
    try:
        guard_candidates = [g for g in guards
                            if guardFilter(g, cons_rel_stats, descriptors,
                                           fast, stable, exit_desc,
                                           exit_status_entry)]
        return random.choice(guard_candidates)
    except IndexError:

# Path: oppy/path/util.py
# def nodeUsableWithOther(desc1, status_entry1, desc2, status_entry2):
# def selectWeightedNode(weighted_nodes):
# def getWeightedNodes(nodes, weights):
# def getPositionWeights(nodes, cons_rel_stats, position, bw_weights,
#                        bwweightscale):
# def getBwweight(flags, position, bw_weights):
# def inSameFamily(desc1, status_entry1, desc2, status_entry2):
# def inSame16Subnet(status_entry1, status_entry2):
# 
# Path: oppy/path/exceptions.py
# class NoUsableGuardsException(Exception):
#     pass
# 
# class PathSelectionFailedException(Exception):
#     pass


# Path: oppy/path/path.py
import random
from collections import namedtuple
from twisted.internet import defer
from stem import Flag
from oppy.path import util as path_util
from oppy.path.exceptions import (
    NoUsableGuardsException,
    PathSelectionFailedException,
)



def selectExitNode(bw_weights, bwweightscale, cons_rel_stats, descriptors,
                   fast, stable, internal, port):
    exits = filterExits(cons_rel_stats, descriptors, fast, stable, internal,
                        port)

    if len(exits) == 0:
        raise ValueError("No usable exit nodes for requested path.")

    if len(exits) == 1:
        return exits[0]

    weight_pos = 'm' if internal is True else 'e'
    weights = path_util.getPositionWeights(exits, cons_rel_stats, weight_pos,
                                           bw_weights, bwweightscale)
    weighted_exits = path_util.getWeightedNodes(exits, weights)

    return path_util.selectWeightedNode(weighted_exits)


def selectGuardNode(cons_rel_stats, descriptors, guards, fast, stable,
                    exit_desc, exit_status_entry):
    try:
        guard_candidates = [g for g in guards
                            if guardFilter(g, cons_rel_stats, descriptors,
                                           fast, stable, exit_desc,
                                           exit_status_entry)]
        return random.choice(guard_candidates)
    except IndexError:

        raise NoUsableGuardsException("No usable guard nodes for requested "