from _typeshed import ConvertibleToInt
from typing import ClassVar, Literal, overload
from typing_extensions import Self

from netaddr.core import DictDotLookup
from netaddr.ip import IPAddress
from netaddr.strategy.eui48 import mac_eui48
from netaddr.strategy.eui64 import eui64_base

class BaseIdentifier:
    __slots__ = ("_value", "__weakref__")
    def __init__(self) -> None: ...
    def __int__(self) -> int: ...
    def __index__(self) -> int: ...

class OUI(BaseIdentifier):
    __slots__ = ("records",)
    records: list[dict[str, object]]
    def __init__(self, oui: str | int) -> None: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    @property
    def reg_count(self) -> int: ...
    def registration(self, index: int = 0) -> DictDotLookup: ...

class IAB(BaseIdentifier):
    __slots__ = ("record",)
    IAB_EUI_VALUES: ClassVar[tuple[int, int]]
    @classmethod
    def split_iab_mac(cls, eui_int: int, strict: bool = False) -> tuple[int, int]: ...
    record: dict[str, object]
    def __init__(self, iab: str | int, strict: bool = False) -> None: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def registration(self) -> DictDotLookup: ...

class EUI(BaseIdentifier):
    __slots__ = ("_module", "_dialect")
    def __init__(
        self, addr: EUI | int | str, version: int | None = None, dialect: type[mac_eui48 | eui64_base] | None = None
    ) -> None: ...

    @property
    def value(self) -> int: ...
    @value.setter
    def value(self, value: ConvertibleToInt) -> None: ...

    @property
    def dialect(self) -> type[mac_eui48 | eui64_base]: ...
    @dialect.setter
    def dialect(self, value: type[mac_eui48 | eui64_base] | None) -> None: ...

    @property
    def oui(self) -> OUI: ...
    @property
    def ei(self) -> str: ...
    def is_iab(self) -> bool: ...
    @property
    def iab(self) -> IAB | None: ...
    @property
    def version(self) -> Literal[48, 64]: ...

    @overload
    def __getitem__(self, idx: int) -> int: ...
    @overload
    def __getitem__(self, idx: slice) -> list[int]: ...
    @overload
    def __getitem__(self, idx: int | slice) -> int | list[int]: ...

    def __setitem__(self, idx: int, value: int) -> None: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __lt__(self, other: EUI | int | str) -> bool: ...
    def __le__(self, other: EUI | int | str) -> bool: ...
    def __gt__(self, other: EUI | int | str) -> bool: ...
    def __ge__(self, other: EUI | int | str) -> bool: ...
    def bits(self, word_sep: str | None = None) -> str: ...
    @property
    def packed(self) -> bytes: ...
    @property
    def words(self) -> tuple[int, ...]: ...
    @property
    def bin(self) -> str: ...
    def eui64(self) -> Self: ...
    def modified_eui64(self) -> Self: ...
    def ipv6(self, prefix: ConvertibleToInt) -> IPAddress: ...
    def ipv6_link_local(self) -> IPAddress: ...
    @property
    def info(self) -> DictDotLookup: ...
    def format(self, dialect: type[mac_eui48 | eui64_base] | None = None) -> str: ...
