from collections.abc import Generator, Iterable, Sequence
from ctypes import Array, Structure, Union, c_uint8, c_uint16, c_uint32, pointer
from enum import IntFlag
from types import TracebackType
from typing import SupportsBytes

I2C_RETRIES: int
I2C_TIMEOUT: int
I2C_SLAVE: int
I2C_SLAVE_FORCE: int
I2C_TENBIT: int
I2C_FUNCS: int
I2C_RDWR: int
I2C_PEC: int
I2C_SMBUS: int
I2C_SMBUS_WRITE: int
I2C_SMBUS_READ: int
I2C_SMBUS_QUICK: int
I2C_SMBUS_BYTE: int
I2C_SMBUS_BYTE_DATA: int
I2C_SMBUS_WORD_DATA: int
I2C_SMBUS_PROC_CALL: int
I2C_SMBUS_BLOCK_DATA: int
I2C_SMBUS_BLOCK_PROC_CALL: int
I2C_SMBUS_I2C_BLOCK_DATA: int
I2C_SMBUS_BLOCK_MAX: int

class I2C_M_Bitflag(IntFlag):
    I2C_M_RD: int = ...
    I2C_M_WR: int = ...
    I2C_M_TEN: int = ...
    I2C_M_RD_TEN: int = ...
    I2C_M_WR_TEN: int = ...

class I2cFunc(IntFlag):
    I2C: int = ...
    ADDR_10BIT: int = ...
    PROTOCOL_MANGLING: int = ...
    SMBUS_PEC: int = ...
    NOSTART: int = ...
    SLAVE: int = ...
    SMBUS_BLOCK_PROC_CALL: int = ...
    SMBUS_QUICK: int = ...
    SMBUS_READ_BYTE: int = ...
    SMBUS_WRITE_BYTE: int = ...
    SMBUS_READ_BYTE_DATA: int = ...
    SMBUS_WRITE_BYTE_DATA: int = ...
    SMBUS_READ_WORD_DATA: int = ...
    SMBUS_WRITE_WORD_DATA: int = ...
    SMBUS_PROC_CALL: int = ...
    SMBUS_READ_BLOCK_DATA: int = ...
    SMBUS_WRITE_BLOCK_DATA: int = ...
    SMBUS_READ_I2C_BLOCK: int = ...
    SMBUS_WRITE_I2C_BLOCK: int = ...
    SMBUS_HOST_NOTIFY: int = ...
    SMBUS_BYTE: int = ...
    SMBUS_BYTE_DATA: int = ...
    SMBUS_WORD_DATA: int = ...
    SMBUS_BLOCK_DATA: int = ...
    SMBUS_I2C_BLOCK: int = ...
    SMBUS_EMUL: int = ...

I2C_M_RD: int
I2C_M_WR: int
I2C_M_TEN: int
LP_c_uint8: type[pointer[c_uint8]]  # type: ignore[valid-type]
LP_c_uint16: type[pointer[c_uint16]]  # type: ignore[valid-type]
LP_c_uint32: type[pointer[c_uint32]]  # type: ignore[valid-type]

i2c_smbus_data: Array = ...

class union_i2c_smbus_data(Union): ...

union_pointer_type: pointer[union_i2c_smbus_data]  # type: ignore[valid-type]

class i2c_smbus_ioctl_data(Structure):
    @staticmethod
    def create(read_write: int = ..., command: int = 0, size: int = ...) -> i2c_smbus_ioctl_data: ...

class i2c_msg(Structure):
    def __iter__(self) -> Generator[int, None, None]: ...
    def __len__(self) -> int: ...
    def __bytes__(self) -> str: ...
    def __repr__(self) -> str: ...
    def __str__(self) -> str: ...
    @staticmethod
    def read(address: int, length: int, flags: int = ...) -> i2c_msg: ...
    @staticmethod
    def write(
        address: int, buf: str | Iterable[int] | SupportsBytes, flags: int = ...
    ) -> i2c_msg: ...

class i2c_rdwr_ioctl_data(Structure):
    @staticmethod
    def create(*i2c_msg_instances: Sequence[i2c_msg]) -> i2c_rdwr_ioctl_data: ...

class SMBus:
    fd: int | None = ...
    funcs: I2cFunc = ...
    address: int | None = ...
    force: bool = ...
    pec: int = ...
    retries: int = ...
    tenbit: int = ...
    timeout: int = ...
    def __init__(self, bus: None | int | str = ..., force: bool = ...) -> None: ...
    def __enter__(self) -> SMBus: ...
    def __exit__(
        self,
        exc_type: type[BaseException] | None,
        exc_val: BaseException | None,
        exc_tb: TracebackType | None,
    ) -> None: ...
    def open(self, bus: int | str) -> None: ...
    def close(self) -> None: ...
    def enable_pec(self, enable: bool = True) -> None: ...
    def enable_tenbit(self, enable: bool = True) -> None: ...
    def set_timeout(self, timeout: int) -> None: ...
    def set_retries(self, retries: int) -> None: ...
    def write_quick(self, i2c_addr: int, force: bool | None = None) -> None: ...
    def read_byte(self, i2c_addr: int, force: bool | None = None) -> int: ...
    def write_byte(self, i2c_addr: int, value: int, force: bool | None = None) -> None: ...
    def read_byte_data(self, i2c_addr: int, register: int, force: bool | None = None) -> int: ...
    def write_byte_data(
        self, i2c_addr: int, register: int, value: int, force: bool | None = None
    ) -> None: ...
    def read_word_data(self, i2c_addr: int, register: int, force: bool | None = None) -> int: ...
    def write_word_data(
        self, i2c_addr: int, register: int, value: int, force: bool | None = None
    ) -> None: ...
    def process_call(self, i2c_addr: int, register: int, value: int, force: bool | None = None): ...
    def read_block_data(
        self, i2c_addr: int, register: int, force: bool | None = None
    ) -> list[int]: ...
    def write_block_data(
        self,
        i2c_addr: int,
        register: int,
        data: Sequence[int],
        force: bool | None = None,
    ) -> None: ...
    def block_process_call(
        self,
        i2c_addr: int,
        register: int,
        data: Sequence[int],
        force: bool | None = None,
    ) -> list[int]: ...
    def read_i2c_block_data(
        self, i2c_addr: int, register: int, length: int, force: bool | None = None
    ) -> list[int]: ...
    def write_i2c_block_data(
        self,
        i2c_addr: int,
        register: int,
        data: Sequence[int],
        force: bool | None = None,
    ) -> None: ...
    def i2c_rdwr(self, *i2c_msgs: i2c_msg) -> None: ...
    def i2c_rd(self, i2c_addr: int, length: int, flags: int = ...) -> i2c_msg: ...
    def i2c_wr(self, i2c_addr: int, buf: Sequence[int], flags: int = ...) -> None: ...
