import itertools as it
import math
from collections import defaultdict, namedtuple

from ...classes.graph import Graph
from ...utils import not_implemented_for, py_random_state

__all__ = ["k_edge_augmentation", "is_k_edge_connected", "is_locally_k_edge_connected"]

def is_k_edge_connected(G: Graph, k) -> bool: ...
def is_locally_k_edge_connected(G: Graph, s, t, k) -> bool: ...
def k_edge_augmentation(
    G: Graph, k, avail=None, weight: str | None = None, partial: bool = False
): ...
def partial_k_edge_augmentation(G: Graph, k, avail, weight: str | None = None): ...
def one_edge_augmentation(
    G: Graph, avail=None, weight: str | None = None, partial: bool = False
): ...
def bridge_augmentation(G: Graph, avail=None, weight: str | None = None): ...

# --- Algorithms and Helpers ---

MetaEdge = ...

def unconstrained_one_edge_augmentation(G: Graph): ...
def weighted_one_edge_augmentation(
    G: Graph, avail, weight: str | None = None, partial: bool = False
): ...
def unconstrained_bridge_augmentation(G: Graph): ...
def weighted_bridge_augmentation(G: Graph, avail, weight: str | None = None): ...
def collapse(G: Graph, grouped_nodes): ...
def complement_edges(G: Graph): ...
@py_random_state(4)
def greedy_k_edge_augmentation(
    G: Graph, k, avail=None, weight: str | None = None, seed=None
): ...
