from typing import Any, IO, Iterator
from .asyncpglib import connect_async as connect_async, AsyncConnection as AsyncConnection

# Module-level functions

def connect(conninfo: str) -> Connection: ...
def defaults() -> dict[str, str]: ...
def connection_count() -> int: ...
def register_type(oid: int, type_name: str) -> None: ...
def register_enum(oid: int) -> None: ...

# Transaction status constants

PQTRANS_IDLE: int
PQTRANS_ACTIVE: int
PQTRANS_INTRANS: int
PQTRANS_INERROR: int
PQTRANS_UNKNOWN: int

# Polling status constants

PGRES_POLLING_READING: int
PGRES_POLLING_WRITING: int
PGRES_POLLING_FAILED: int
PGRES_POLLING_OK: int

# Error class

class Error(Exception):
    severity: str | None
    sqlstate: str | None
    detail: str | None
    hint: str | None
    position: str | None
    internal_position: str | None
    internal_query: str | None
    context: str | None
    file: str | None
    line: str | None
    function: str | None

# Connection class

class Connection:
    @property
    def server_version(self) -> int: ...
    @property
    def protocol_version(self) -> int: ...
    @property
    def server_encoding(self) -> str: ...
    @property
    def client_encoding(self) -> str: ...
    @property
    def status(self) -> bool: ...
    @property
    def transaction_status(self) -> int: ...
    @property
    def socket(self) -> int: ...
    @property
    def pid(self) -> int: ...

    def execute(self, sql: str, *params: Any) -> ResultSet | int | None: ...
    def fetchall(self, sql: str, *params: Any) -> ResultSet | int | None: ...
    def fetchrow(self, sql: str, *params: Any) -> Row | None: ...
    def fetchval(self, sql: str, *params: Any) -> Any: ...
    def fetchvals(self, sql: str, *params: Any) -> list[Any]: ...
    def row(self, sql: str, *params: Any) -> Row | None: ...
    def scalar(self, sql: str, *params: Any) -> Any: ...
    def script(self, sql: str) -> None: ...

    def copy_from(self, command: str, source: str | IO[Any]) -> int | None: ...
    def copy_from_csv(
        self,
        table: str,
        source: str | IO[Any],
        *,
        header: bool = ...,
        delimiter: str = ...,
        quote: str = ...,
    ) -> int | None: ...
    def copy_to(self, command: str, dest: IO[Any]) -> int | None: ...
    def copy_to_csv(
        self,
        table: str,
        dest: IO[Any],
        *,
        header: bool = ...,
        delimiter: str = ...,
        quote: str = ...,
    ) -> int | None: ...

    def begin(self) -> None: ...
    def commit(self) -> None: ...
    def rollback(self) -> None: ...
    def close(self) -> None: ...
    def reset(self) -> None: ...
    def trace(self, filename: str | None, mode: str = ...) -> None: ...
    def notify(self, channel: str, payload: str | None = ...) -> ResultSet | int | None: ...
    def notifications(self, *, timeout: float | None = ...) -> tuple[str, str | None] | None: ...
    def info(self) -> dict[str, str]: ...

# ResultSet class

class ResultSet:
    @property
    def columns(self) -> tuple[str, ...]: ...
    @property
    def rowcount(self) -> int: ...
    @property
    def colinfos(self) -> tuple[ColInfo, ...]: ...

    def __len__(self) -> int: ...
    def __getitem__(self, index: int) -> Row: ...
    def __iter__(self) -> Iterator[Row]: ...

# ColInfo struct sequence

class ColInfo(tuple):
    name: str
    type: int
    mod: int
    size: int

# Row class

class Row:
    columns: tuple[str, ...]
    def __len__(self) -> int: ...
    def __getitem__(self, index: int) -> Any: ...
    def __setitem__(self, index: int, value: Any) -> None: ...
    def __iter__(self) -> Iterator[Any]: ...
    def __getattr__(self, name: str) -> Any: ...
    def __setattr__(self, name: str, value: Any) -> None: ...

# Wrapper types

class hstore:
    data: dict[str, str | None]
    def __init__(self, data: dict[str, str | None]) -> None: ...

class json:
    data: Any
    def __init__(self, data: Any) -> None: ...
