import sys

if sys.platform == "linux":
    import enum
    import re
    from _typeshed import FileDescriptorOrPath
    from collections import defaultdict
    from collections.abc import Callable, Generator, Sequence
    from typing import Final, TypeVar, overload
    from typing_extensions import ParamSpec

    from psutil._common import (
        ENCODING as ENCODING,
        NIC_DUPLEX_FULL as NIC_DUPLEX_FULL,
        NIC_DUPLEX_HALF as NIC_DUPLEX_HALF,
        NIC_DUPLEX_UNKNOWN as NIC_DUPLEX_UNKNOWN,
        AccessDenied as AccessDenied,
        NoSuchProcess as NoSuchProcess,
        ZombieProcess as ZombieProcess,
        bcat as bcat,
        cat as cat,
        debug as debug,
        decode as decode,
        get_procfs_path as get_procfs_path,
        isfile_strict as isfile_strict,
        memoize as memoize,
        memoize_when_activated as memoize_when_activated,
        open_binary as open_binary,
        open_text as open_text,
        parse_environ_block as parse_environ_block,
        path_exists_strict as path_exists_strict,
        supports_ipv6 as supports_ipv6,
        usage_percent as usage_percent,
    )

    from . import _ntuples as ntp, _psposix, _psutil_linux

    _P = ParamSpec("_P")
    _R = TypeVar("_R")

    __extra__all__: Final[list[str]]
    POWER_SUPPLY_PATH: Final = "/sys/class/power_supply"
    HAS_PROC_SMAPS: Final[bool]
    HAS_PROC_SMAPS_ROLLUP: Final[bool]
    HAS_PROC_IO_PRIORITY: Final[bool]
    HAS_CPU_AFFINITY: Final[bool]
    CLOCK_TICKS: Final[int]
    PAGESIZE: Final[int]
    LITTLE_ENDIAN: Final[bool]
    UNSET: object
    DISK_SECTOR_SIZE: Final = 512

    class AddressFamily(enum.IntEnum):
        AF_LINK = 17  # = socket.AF_PACKET

    AF_LINK: Final = AddressFamily.AF_LINK

    class IOPriority(enum.IntEnum):
        IOPRIO_CLASS_NONE = 0
        IOPRIO_CLASS_RT = 1
        IOPRIO_CLASS_BE = 2
        IOPRIO_CLASS_IDLE = 3

    IOPRIO_CLASS_NONE: Final = IOPriority.IOPRIO_CLASS_NONE
    IOPRIO_CLASS_RT: Final = IOPriority.IOPRIO_CLASS_RT
    IOPRIO_CLASS_BE: Final = IOPriority.IOPRIO_CLASS_BE
    IOPRIO_CLASS_IDLE: Final = IOPriority.IOPRIO_CLASS_IDLE

    PROC_STATUSES: Final[dict[str, str]]
    TCP_STATUSES: Final[dict[str, str]]

    def readlink(path: str) -> str: ...
    def file_flags_to_mode(flags: int) -> str: ...
    def is_storage_device(name: str) -> bool: ...
    def _scputimes_ntuple(procfs_path: str) -> type[ntp.scputimes]: ...
    scputimes = ntp.scputimes
    def calculate_avail_vmem(mems: dict[bytes, int]) -> int: ...
    def virtual_memory() -> ntp.svmem: ...
    def swap_memory() -> ntp.sswap: ...
    heap_info = _psutil_linux.heap_info
    heap_trim = _psutil_linux.heap_trim
    def cpu_times() -> ntp.scputimes: ...
    def per_cpu_times() -> list[ntp.scputimes]: ...
    def cpu_count_logical() -> int | None: ...
    def cpu_count_cores() -> int | None: ...
    def cpu_stats() -> ntp.scpustats: ...
    def cpu_freq() -> list[ntp.scpufreq]: ...

    net_if_addrs = _psutil_linux.net_if_addrs

    class _Ipv6UnsupportedError(Exception): ...

    class NetConnections:
        tmap: dict[str, tuple[tuple[str, int, int | None], ...]]
        def __init__(self) -> None: ...
        def get_proc_inodes(self, pid: int) -> defaultdict[str, list[tuple[int, int]]]: ...
        def get_all_inodes(self) -> dict[str, list[tuple[int, int]]]: ...
        @staticmethod
        def decode_address(addr: str, family: int) -> ntp.addr | tuple[()]: ...
        @staticmethod
        def process_inet(
            file: str, family: int, type_: int, inodes: dict[str, list[tuple[int, int]]], filter_pid: int | None = None
        ) -> Generator[tuple[int, int, int, ntp.addr | tuple[()], ntp.addr | tuple[()], str, int | None]]: ...
        @staticmethod
        def process_unix(
            file: FileDescriptorOrPath, family: int, inodes: dict[str, list[tuple[int, int]]], filter_pid: int | None = None
        ) -> Generator[tuple[int, int, int, str, str, str, int | None]]: ...
        @overload
        def retrieve(self, kind: str, pid: int) -> list[ntp.pconn]: ...
        @overload
        def retrieve(self, kind: str, pid: None = None) -> list[ntp.sconn]: ...

    def net_connections(kind: str = "inet") -> list[ntp.sconn]: ...
    def net_io_counters() -> dict[str, tuple[int, int, int, int, int, int, int, int]]: ...
    def net_if_stats() -> dict[str, ntp.snicstats]: ...

    disk_usage = _psposix.disk_usage

    def disk_io_counters(perdisk: bool = False) -> dict[str, tuple[int, int, int, int, int, int, int, int]]: ...

    class RootFsDeviceFinder:
        __slots__ = ["major", "minor"]
        major: int
        minor: int
        def __init__(self) -> None: ...
        def ask_proc_partitions(self) -> str | None: ...
        def ask_sys_dev_block(self) -> str | None: ...
        def ask_sys_class_block(self) -> str | None: ...
        def find(self) -> str | None: ...

    def disk_partitions(all: bool = False) -> list[ntp.sdiskpart]: ...
    def sensors_temperatures() -> dict[str, list[tuple[str, float, float | None, float | None]]]: ...
    def sensors_fans() -> dict[str, list[ntp.sfan]]: ...
    def sensors_battery() -> ntp.sbattery | None: ...
    def users() -> list[ntp.suser]: ...
    def boot_time() -> float: ...
    def pids() -> list[int]: ...
    def pid_exists(pid: int) -> bool: ...
    def ppid_map() -> dict[int, int]: ...
    def wrap_exceptions(fun: Callable[_P, _R]) -> Callable[_P, _R]: ...

    class Process:
        __slots__ = ["_cache", "_ctime", "_name", "_ppid", "_procfs_path", "pid"]
        pid: int
        def __init__(self, pid: int) -> None: ...
        def oneshot_enter(self) -> None: ...
        def oneshot_exit(self) -> None: ...
        def name(self) -> str: ...
        def exe(self) -> str: ...
        def cmdline(self) -> list[str]: ...
        def environ(self) -> dict[str, str]: ...
        def terminal(self) -> str | None: ...
        def io_counters(self) -> ntp.pio: ...
        def cpu_times(self) -> ntp.pcputimes: ...
        def cpu_num(self) -> int: ...
        def wait(self, timeout: float | None = None) -> int | None: ...
        def create_time(self, monotonic: bool = False) -> float: ...
        def memory_info(self) -> ntp.pmem: ...
        def memory_full_info(self) -> ntp.pfullmem: ...
        def memory_maps(self) -> list[tuple[str, str, str, int, int, int, int, int, int, int, int, int, int]]: ...
        def cwd(self) -> str: ...
        def num_ctx_switches(self, _ctxsw_re: re.Pattern[bytes] = ...) -> ntp.pctxsw: ...
        def num_threads(self, _num_threads_re: re.Pattern[bytes] = ...) -> int: ...
        def threads(self) -> list[ntp.pthread]: ...
        def nice_get(self) -> int: ...
        def nice_set(self, value: int) -> None: ...
        def cpu_affinity_get(self) -> list[int]: ...
        def cpu_affinity_set(self, cpus: Sequence[int]) -> None: ...
        def ionice_get(self) -> ntp.pionice: ...
        def ionice_set(self, ioclass: int, value: int | None) -> None: ...
        @overload
        def rlimit(self, resource_: int, limits: tuple[int, int]) -> None: ...
        @overload
        def rlimit(self, resource_: int, limits: None = None) -> tuple[int, int]: ...
        def status(self) -> str: ...
        def open_files(self) -> list[ntp.popenfile]: ...
        def net_connections(self, kind: str = "inet") -> list[ntp.pconn]: ...
        def num_fds(self) -> int: ...
        def ppid(self) -> int: ...
        def uids(self, _uids_re: re.Pattern[bytes] = ...) -> ntp.puids: ...
        def gids(self, _gids_re: re.Pattern[bytes] = ...) -> ntp.pgids: ...
