from collections.abc import Mapping, Set as AbstractSet
from typing import Any

from ..classes.graph import Graph
from ..classes.reportviews import NodeDataView

__all__ = [
    "NodeView",
    "NodeDataView",
    "EdgeView",
    "OutEdgeView",
    "InEdgeView",
    "EdgeDataView",
    "OutEdgeDataView",
    "InEdgeDataView",
    "MultiEdgeView",
    "OutMultiEdgeView",
    "InMultiEdgeView",
    "MultiEdgeDataView",
    "OutMultiEdgeDataView",
    "InMultiEdgeDataView",
    "DegreeView",
    "DiDegreeView",
    "InDegreeView",
    "OutDegreeView",
    "MultiDegreeView",
    "DiMultiDegreeView",
    "InMultiDegreeView",
    "OutMultiDegreeView",
]

# NodeViews
class NodeView(Mapping, AbstractSet):
    __slots__ = ...

    def __getstate__(self): ...
    def __setstate__(self, state): ...
    def __init__(self, graph): ...

    # Mapping methods
    def __len__(self): ...
    def __iter__(self): ...
    def __getitem__(self, n): ...

    # Set methods
    def __contains__(self, n): ...
    @classmethod
    def _from_iterable(cls, it): ...

    # DataView method
    def __call__(self, data=False, default=None): ...
    def data(self, data=True, default: Any = None) -> NodeDataView: ...
    def __str__(self): ...
    def __repr__(self): ...

class NodeDataView(AbstractSet):
    __slots__ = ...

    def __getstate__(self): ...
    def __setstate__(self, state): ...
    def __init__(self, nodedict, data=False, default=None): ...
    @classmethod
    def _from_iterable(cls, it): ...
    def __len__(self): ...
    def __iter__(self): ...
    def __contains__(self, n): ...
    def __getitem__(self, n): ...
    def __str__(self): ...
    def __repr__(self): ...

# DegreeViews
class DiDegreeView:
    def __init__(self, G: Graph, nbunch=None, weight=None): ...
    def __call__(self, nbunch=None, weight=None): ...
    def __getitem__(self, n): ...
    def __iter__(self): ...
    def __len__(self): ...
    def __str__(self): ...
    def __repr__(self): ...

class DegreeView(DiDegreeView):
    def __getitem__(self, n): ...
    def __iter__(self): ...

class OutDegreeView(DiDegreeView):
    def __getitem__(self, n): ...
    def __iter__(self): ...

class InDegreeView(DiDegreeView):
    def __getitem__(self, n): ...
    def __iter__(self): ...

class MultiDegreeView(DiDegreeView):
    def __getitem__(self, n): ...
    def __iter__(self): ...

class DiMultiDegreeView(DiDegreeView):
    def __getitem__(self, n): ...
    def __iter__(self): ...

class InMultiDegreeView(DiDegreeView):
    def __getitem__(self, n): ...
    def __iter__(self): ...

class OutMultiDegreeView(DiDegreeView):
    def __getitem__(self, n): ...
    def __iter__(self): ...

# EdgeDataViews
class OutEdgeDataView:
    __slots__ = ...

    def __getstate__(self): ...
    def __setstate__(self, state): ...
    def __init__(self, viewer, nbunch=None, data=False, default=None): ...
    def __len__(self): ...
    def __iter__(self): ...
    def __contains__(self, e): ...
    def __str__(self): ...
    def __repr__(self): ...

class EdgeDataView(OutEdgeDataView):
    __slots__ = ...

    def __len__(self): ...
    def __iter__(self): ...
    def __contains__(self, e): ...

class InEdgeDataView(OutEdgeDataView):
    __slots__ = ...

    def __iter__(self): ...
    def __contains__(self, e): ...

class OutMultiEdgeDataView(OutEdgeDataView):
    __slots__ = ...

    def __getstate__(self): ...
    def __setstate__(self, state): ...
    def __init__(self, viewer, nbunch=None, data=False, keys=False, default=None): ...
    def __len__(self): ...
    def __iter__(self): ...
    def __contains__(self, e): ...

class MultiEdgeDataView(OutMultiEdgeDataView):
    __slots__ = ...

    def __iter__(self): ...
    def __contains__(self, e): ...

class InMultiEdgeDataView(OutMultiEdgeDataView):
    __slots__ = ...

    def __iter__(self): ...
    def __contains__(self, e): ...

# EdgeViews    have set operations and no data reported
class OutEdgeView(AbstractSet, Mapping):
    __slots__ = ...

    def __getstate__(self): ...
    def __setstate__(self, state): ...
    @classmethod
    def _from_iterable(cls, it): ...

    dataview = ...

    def __init__(self, G): ...

    # Set methods
    def __len__(self): ...
    def __iter__(self): ...
    def __contains__(self, e): ...

    # Mapping Methods
    def __getitem__(self, e): ...

    # EdgeDataView methods
    def __call__(self, nbunch=None, data=False, default=None): ...
    def data(self, data=True, default: Any = None, nbunch=None): ...

    # String Methods
    def __str__(self): ...
    def __repr__(self): ...

class EdgeView(OutEdgeView):
    __slots__ = ...

    dataview = ...

    def __len__(self): ...
    def __iter__(self): ...
    def __contains__(self, e): ...

class InEdgeView(OutEdgeView):
    __slots__ = ...

    def __setstate__(self, state): ...

    dataview = ...

    def __init__(self, G): ...
    def __iter__(self): ...
    def __contains__(self, e): ...
    def __getitem__(self, e): ...

class OutMultiEdgeView(OutEdgeView):
    __slots__ = ...

    dataview = ...

    def __len__(self): ...
    def __iter__(self): ...
    def __contains__(self, e): ...
    def __getitem__(self, e): ...
    def __call__(self, nbunch=None, data=False, keys=False, default=None): ...
    def data(self, data=True, keys=False, default: Any = None, nbunch=None): ...

class MultiEdgeView(OutMultiEdgeView):
    __slots__ = ...

    dataview = ...

    def __len__(self): ...
    def __iter__(self): ...

class InMultiEdgeView(OutMultiEdgeView):
    __slots__ = ...

    def __setstate__(self, state): ...

    dataview = ...

    def __init__(self, G): ...
    def __iter__(self): ...
    def __contains__(self, e): ...
    def __getitem__(self, e): ...
