# This file is automatically generated by pyo3_stub_gen
# ruff: noqa: E501, F401

import builtins
import typing
from enum import Enum, auto

class PyKey:
    r"""
    Composite key description used for signing or verification.
    
    Fields:
    * algorithm: `PyAlgorithm` to apply
    * format: `PyKeyFormat` describing encoding
    * key: `PyKeyData` where the actual bytes originate
    """
    algorithm: PyAlgorithm
    format: PyKeyFormat
    key: PyKeyData
    def __new__(cls,algorithm:PyAlgorithm, format:PyKeyFormat, key:PyKeyData): ...

class PyMessageContext:
    r"""
    Python-visible context accompanying every received message.
    
    Provides routing and descriptive metadata needed for replying,
    auditing, and instrumentation.
    
    Fields:
    * `source_name`: Fully-qualified sender identity.
    * `destination_name`: Fully-qualified destination identity (may be an empty placeholder
      when not explicitly set, e.g. broadcast/group scenarios).
    * `payload_type`: Logical/semantic type (defaults to "msg" if unspecified).
    * `metadata`: Arbitrary key/value pairs supplied by the sender (e.g. tracing IDs).
    * `input_connection`: Numeric identifier of the inbound connection carrying the message.
    """
    source_name: PyName
    destination_name: PyName
    payload_type: builtins.str
    metadata: builtins.dict[builtins.str, builtins.str]
    input_connection: builtins.int
    def __new__(cls,): ...

class PyName:
    r"""
    name class
    """
    id: builtins.int
    def __new__(cls,component0:builtins.str, component1:builtins.str, component2:builtins.str, id:typing.Optional[builtins.int]=None): ...
    def set_id(self, id:builtins.int) -> None:
        ...

    def components(self) -> builtins.list[builtins.int]:
        ...

    def components_strings(self) -> builtins.list[builtins.str]:
        ...

    def equal_without_id(self, name:PyName) -> builtins.bool:
        ...

    def __hash__(self) -> builtins.int:
        ...


class PyService:
    id: builtins.int
    name: PyName

class PySessionContext:
    r"""
    Python-exposed session context wrapper.
    
    A thin, cloneable handle around the underlying Rust session state. All
    getters perform a safe upgrade of the weak internal session reference,
    returning a Python exception if the session has already been closed.
    The internal message receiver is intentionally not exposed at this level.
    
    Higher-level Python code (see `session.py`) provides ergonomic async
    operations on top of this context.
    
    Properties (getters exposed to Python):
    - id -> int: Unique numeric identifier of the session. Raises a Python
      exception if the session has been closed.
    - metadata -> dict[str,str]: Arbitrary key/value metadata copied from the
      current SessionConfig. A cloned map is returned so Python can mutate
      without racing the underlying config.
    - session_type -> PySessionType: High-level transport classification
      (PointToPoint, Group), inferred from internal kind + destination.
    - src -> PyName: Fully qualified source identity that originated / owns
      the session.
    - dst -> PyName: Destination name:
        * PyName of the peer for PointToPoint
        * PyName of the channel for Group
    - session_config -> PySessionConfiguration: Current effective configuration
      converted to the Python-facing enum variant.
    """
    id: builtins.int
    metadata: builtins.dict[builtins.str, builtins.str]
    session_type: PySessionType
    src: PyName
    dst: typing.Optional[PyName]
    session_config: PySessionConfiguration
    def set_session_config(self, config:PySessionConfiguration) -> None:
        ...


class PyAlgorithm(Enum):
    r"""
    JWT / signature algorithms exposed to Python.
    
    Maps 1:1 to `slim_auth::jwt::Algorithm`.
    Provides stable integer values for stub generation / introspection.
    """
    HS256 = auto()
    HS384 = auto()
    HS512 = auto()
    RS256 = auto()
    RS384 = auto()
    RS512 = auto()
    PS256 = auto()
    PS384 = auto()
    PS512 = auto()
    ES256 = auto()
    ES384 = auto()
    EdDSA = auto()

class PyIdentityProvider(Enum):
    r"""
    Python-facing identity provider definitions.
    
    Variants:
    * StaticJwt { path }: Load a token from a file (cached, static).
    * Jwt { private_key, duration, issuer?, audience?, subject? }:
        Dynamically sign tokens using provided private key with optional
        standard JWT claims (iss, aud, sub) and a token validity duration.
    * SharedSecret { identity, shared_secret }:
        Symmetric token provider using a shared secret. Used mainly for testing.
    
    Examples (Python):
    
    Static (pre-issued) JWT token loaded from a file:
    ```python
    from slim_bindings import PyIdentityProvider
    
    provider = PyIdentityProvider.StaticJwt(path="service.token")
    # 'provider.get_token()' (internally) will manage reloading of the file if it changes.
    ```
    
    Dynamically signed JWT using a private key (claims + duration):
    ```python
    from slim_bindings import (
        PyIdentityProvider, PyKey, PyAlgorithm, PyKeyFormat, PyKeyData
    )
    import datetime
    
    signing_key = PyKey(
        algorithm=PyAlgorithm.RS256,
        format=PyKeyFormat.Pem,
        key=PyKeyData.File("private_key.pem"),
    )
    
    provider = PyIdentityProvider.Jwt(
        private_key=signing_key,
        duration=datetime.timedelta(minutes=30),
        issuer="my-issuer",
        audience=["downstream-svc"],
        subject="svc-a",
    )
    ```
    
    Shared secret token provider for tests / local development:
    ```python
    from slim_bindings import PyIdentityProvider
    
    provider = PyIdentityProvider.SharedSecret(
        identity="svc-a",
        shared_secret="not-for-production",
    )
    ```
    
    End-to-end example pairing with a verifier:
    ```python
    # For a simple shared-secret flow:
    from slim_bindings import PyIdentityProvider, PyIdentityVerifier
    
    provider = PyIdentityProvider.SharedSecret(identity="svc-a", shared_secret="dev-secret")
    verifier = PyIdentityVerifier.SharedSecret(identity="svc-a", shared_secret="dev-secret")
    
    # Pass both into Slim.new(local_name, provider, verifier)
    ```
    
    Jwt variant quick start (full):
    ```python
    import datetime
    from slim_bindings import (
        PyIdentityProvider, PyIdentityVerifier,
        PyKey, PyAlgorithm, PyKeyFormat, PyKeyData
    )
    
    key = PyKey(PyAlgorithm.RS256, PyKeyFormat.Pem, PyKeyData.File("private_key.pem"))
    provider = PyIdentityProvider.Jwt(
        private_key=key,
        duration=datetime.timedelta(hours=1),
        issuer="my-issuer",
        audience=["svc-b"],
        subject="svc-a"
    )
    # Verifier would normally use the corresponding public key (PyIdentityVerifier.Jwt).
    ```
    """
    StaticJwt = auto()
    Jwt = auto()
    SharedSecret = auto()

class PyIdentityVerifier(Enum):
    r"""
    Python-facing identity verifier definitions.
    
    Variants:
    * Jwt { public_key?, autoresolve, issuer?, audience?, subject?, require_* }:
        Verifies tokens using a public key or via JWKS auto-resolution.
        `require_iss`, `require_aud`, `require_sub` toggle mandatory presence
        of the respective claims. `autoresolve=True` enables JWKS retrieval
        (public_key must be omitted in that case).
    * SharedSecret { identity, shared_secret }:
        Verifies tokens generated with the same shared secret.
    
    JWKS Auto-Resolve:
      When `autoresolve=True`, the verifier will attempt to resolve keys
      dynamically (e.g. from a JWKS endpoint) if supported by the underlying
      implementation.
    
    Safety:
      A direct panic occurs if neither `public_key` nor `autoresolve=True`
      is provided for the Jwt variant (invalid configuration).
    
    Autoresolve key selection (concise algorithm):
    1. If a static JWKS was injected, use it directly.
    2. Else if a cached JWKS for the issuer exists and is within TTL, use it.
    3. Else discover JWKS:
       - Try {issuer}/.well-known/openid-configuration for "jwks_uri"
       - Fallback to {issuer}/.well-known/jwks.json
    4. Fetch & cache the JWKS (default TTL ~1h unless overridden).
    5. If JWT header has 'kid', pick the matching key ID; otherwise choose the
       first key whose algorithm matches the token header's alg.
    6. Convert JWK -> DecodingKey and verify signature; then enforce required
       claims (iss/aud/sub) per the require_* flags.
    
    # Examples (Python)
    
    Basic JWT verification with explicit public key:
    ```python
    pub_key = PyKey(
        PyAlgorithm.RS256,
        PyKeyFormat.Pem,
        PyKeyData.File("public_key.pem"),
    )
    verifier = PyIdentityVerifier.Jwt(
        public_key=pub_key,
        autoresolve=False,
        issuer="my-issuer",
        audience=["service-b"],
        subject="service-a",
        require_iss=True,
        require_aud=True,
        require_sub=True,
    )
    ```
    
    Auto-resolving JWKS (no public key provided):
    ```python
    # The underlying implementation must know how / where to resolve JWKS.
    verifier = PyIdentityVerifier.Jwt(
        public_key=None,
        autoresolve=True,
        issuer="https://auth.example.com",
        audience=["svc-cluster"],
        subject=None,
        require_iss=True,
        require_aud=True,
        require_sub=False,
    )
    ```
    
    Shared secret verifier (symmetric):
    ```python
    verifier = PyIdentityVerifier.SharedSecret(
        identity="service-a",
        shared_secret="super-secret-value",
    )
    ```
    
    Pairing with a provider when constructing Slim:
    ```python
    provider = PyIdentityProvider.SharedSecret(
        identity="service-a",
        shared_secret="super-secret-value",
    )
    slim = await Slim.new(local_name, provider, verifier)
    ```
    
    Enforcing strict claims (reject tokens missing aud/sub):
    ```python
    strict_verifier = PyIdentityVerifier.Jwt(
        public_key=pub_key,
        autoresolve=False,
        issuer="my-issuer",
        audience=["service-a"],
        subject="service-a",
        require_iss=True,
        require_aud=True,
        require_sub=True,
    )
    ```
    """
    Jwt = auto()
    SharedSecret = auto()

class PyKeyData(Enum):
    r"""
    Key material origin.
    
    Either a path on disk (`File`) or inline string content (`Content`)
    containing the encoded key. The interpretation depends on the
    accompanying `PyKeyFormat`.
    """
    File = auto()
    Content = auto()

class PyKeyFormat(Enum):
    r"""
    Supported key encoding formats.
    
    Used during parsing / loading of provided key material.
    """
    Pem = auto()
    Jwk = auto()
    Jwks = auto()

class PySessionConfiguration(Enum):
    r"""
    User-facing configuration for establishing and tuning sessions.
    
    Each variant maps to a core `SessionConfig`.
    Common fields (casual rundown):
    * `timeout`: How long we wait for an ack before trying again.
    * `max_retries`: Number of attempts to send a message. If we run out, an error is returned.
    * `mls_enabled`: Turn on MLS for end‑to‑end crypto.
    * `metadata`: One-shot string key/value tags sent at session start; the other side can read them for tracing, routing, auth, etc.
    
    Variant-specific notes:
    * `PointToPoint`: PointToPoint will target a specific peer for all messages.
    * `Group`: Uses a named channel and distributes to multiple subscribers.
    
    # Examples
    
    ## Python: Create different session configs
    ```python
    from slim_bindings import PySessionConfiguration, PyName
    
    # PointToPoint session. Wait up to 2 seconds for an ack for each message, retry up to 5 times,
    # enable MLS, and attach some metadata.
    p2p_cfg = PySessionConfiguration.PointToPoint(
        peer_name=PyName("org", "namespace", "service"), # target peer
        timeout=datetime.timedelta(seconds=2), # wait 2 seconds for an ack
        max_retries=5, # retry up to 5 times
        mls_enabled=True, # enable MLS
        metadata={"trace_id": "1234abcd"} # arbitrary (string -> string) key/value pairs to send at session establishment
    )
    
    # Group session (channel-based)
    channel = PyName("org", "namespace", "channel")
    group_cfg = PySessionConfiguration.Group(
        channel_name=channel, # group channel_name
        max_retries=2, # retry up to 2 times
        timeout=datetime.timedelta(seconds=2), # wait 2 seconds for an ack
        mls_enabled=True, # enable MLS
        metadata={"role": "publisher"} # arbitrary (string -> string) key/value pairs to send at session establishment
    )
    ```
    
    ## Python: Using a config when creating a session
    ```python
    slim = await Slim.new(local_name, provider, verifier)
    session = await slim.create_session(p2p_cfg)
    print("Session ID:", session.id)
    print("Type:", session.session_type)
    print("Metadata:", session.metadata)
    ```
    
    ## Python: Updating configuration after creation
    ```python
    # Adjust retries & metadata dynamically
    new_cfg = PySessionConfiguration.PointToPoint(
        peer_name=PyName("org", "namespace", "service"),
        timeout=None,
        max_retries=10,
        mls_enabled=True,
        metadata={"trace_id": "1234abcd", "phase": "retrying"}
    )
    session.set_session_config(new_cfg)
    ```
    
    ## Rust (internal conversion flow)
    The enum transparently converts to and from `session::SessionConfig`:
    ```rust
    let core: session::SessionConfig = py_cfg.clone().into();
    let roundtrip: PySessionConfiguration = core.into();
    assert_eq!(py_cfg, roundtrip);
    ```
    """
    PointToPoint = auto()
    Group = auto()

class PySessionType(Enum):
    r"""
    High-level session classification presented to Python.
    """
    PointToPoint = auto()
    Group = auto()

def connect(svc:PyService, config:dict) -> typing.Any:
    ...

def create_pyservice(name:PyName, provider:PyIdentityProvider, verifier:PyIdentityVerifier, local_service:builtins.bool=False) -> typing.Any:
    ...

def create_session(svc:PyService, config:PySessionConfiguration) -> typing.Any:
    ...

def delete_session(svc:PyService, session_context:PySessionContext) -> typing.Any:
    ...

def disconnect(svc:PyService, conn:builtins.int) -> typing.Any:
    ...

def get_message(svc:PyService, session_context:PySessionContext) -> typing.Any:
    ...

def init_tracing(config:dict) -> typing.Any:
    ...

def invite(svc:PyService, session_context:PySessionContext, name:PyName) -> typing.Any:
    ...

def listen_for_session(svc:PyService) -> typing.Any:
    ...

def publish(svc:PyService, session_context:PySessionContext, fanout:builtins.int, blob:typing.Sequence[builtins.int], message_ctx:typing.Optional[PyMessageContext]=None, name:typing.Optional[PyName]=None, payload_type:typing.Optional[builtins.str]=None, metadata:typing.Optional[typing.Mapping[builtins.str, builtins.str]]=None) -> typing.Any:
    ...

def remove(svc:PyService, session_context:PySessionContext, name:PyName) -> typing.Any:
    ...

def remove_route(svc:PyService, name:PyName, conn:builtins.int) -> typing.Any:
    ...

def run_server(svc:PyService, config:dict) -> typing.Any:
    ...

def set_default_session_config(svc:PyService, config:PySessionConfiguration) -> None:
    ...

def set_route(svc:PyService, name:PyName, conn:builtins.int) -> typing.Any:
    ...

def stop_server(svc:PyService, endpoint:builtins.str) -> typing.Any:
    ...

def subscribe(svc:PyService, name:PyName, conn:typing.Optional[builtins.int]=None) -> typing.Any:
    ...

def unsubscribe(svc:PyService, name:PyName, conn:typing.Optional[builtins.int]=None) -> typing.Any:
    ...

