"""
This type stub file was generated by pyright.
"""

import threading
from abc import abstractmethod
from typing import Any, Callable, Final, TYPE_CHECKING
from streamlit.runtime.caching.cached_message_replay import CachedMessageReplayContext, CachedResult, MsgData
from streamlit.runtime.caching.hashing import HashFuncsDict
from types import FunctionType
from streamlit.runtime.caching.cache_type import CacheType

"""Common cache logic shared by st.cache_data and st.cache_resource."""
if TYPE_CHECKING:
    ...
_LOGGER: Final = ...
TTLCACHE_TIMER = ...
class Cache:
    """Function cache interface. Caches persist across script runs."""
    def __init__(self) -> None:
        ...
    
    @abstractmethod
    def read_result(self, value_key: str) -> CachedResult:
        """Read a value and associated messages from the cache.

        Raises
        ------
        CacheKeyNotFoundError
            Raised if value_key is not in the cache.

        """
        ...
    
    @abstractmethod
    def write_result(self, value_key: str, value: Any, messages: list[MsgData]) -> None:
        """Write a value and associated messages to the cache, overwriting any existing
        result that uses the value_key.
        """
        ...
    
    def compute_value_lock(self, value_key: str) -> threading.Lock:
        """Return the lock that should be held while computing a new cached value.
        In a popular app with a cache that hasn't been pre-warmed, many sessions may try
        to access a not-yet-cached value simultaneously. We use a lock to ensure that
        only one of those sessions computes the value, and the others block until
        the value is computed.
        """
        ...
    
    def clear(self, key: str | None = ...): # -> None:
        """Clear values from this cache.
        If no argument is passed, all items are cleared from the cache.
        A key can be passed to clear that key from the cache only.
        """
        ...
    


class CachedFuncInfo:
    """Encapsulates data for a cached function instance.

    CachedFuncInfo instances are scoped to a single script run - they're not
    persistent.
    """
    def __init__(self, func: FunctionType, show_spinner: bool | str, hash_funcs: HashFuncsDict | None) -> None:
        ...
    
    @property
    def cache_type(self) -> CacheType:
        ...
    
    @property
    def cached_message_replay_ctx(self) -> CachedMessageReplayContext:
        ...
    
    def get_function_cache(self, function_key: str) -> Cache:
        """Get or create the function cache for the given key."""
        ...
    


def make_cached_func_wrapper(info: CachedFuncInfo) -> Callable[..., Any]:
    """Create a callable wrapper around a CachedFunctionInfo.

    Calling the wrapper will return the cached value if it's already been
    computed, and will call the underlying function to compute and cache the
    value otherwise.

    The wrapper also has a `clear` function that can be called to clear
    some or all of the wrapper's cached values.
    """
    ...

class BoundCachedFunc:
    """A wrapper around a CachedFunc that binds it to a specific instance in case of
    decorated function is a class method.
    """
    def __init__(self, cached_func: CachedFunc, instance: Any) -> None:
        ...
    
    def __call__(self, *args, **kwargs) -> Any:
        ...
    
    def __repr__(self): # -> str:
        ...
    
    def clear(self, *args, **kwargs): # -> None:
        ...
    


class CachedFunc:
    def __init__(self, info: CachedFuncInfo) -> None:
        ...
    
    def __repr__(self): # -> str:
        ...
    
    def __get__(self, instance, owner=...): # -> Self | _Wrapped[Callable[..., Any], Any, Callable[..., Any], Any]:
        """CachedFunc implements descriptor protocol to support cache methods."""
        ...
    
    def __call__(self, *args, **kwargs) -> Any:
        """The wrapper. We'll only call our underlying function on a cache miss."""
        ...
    
    def clear(self, *args, **kwargs): # -> None:
        """Clear the cached function's associated cache.

        If no arguments are passed, Streamlit will clear all values cached for
        the function. If arguments are passed, Streamlit will clear the cached
        value for these arguments only.

        Parameters
        ----------
        *args: Any
            Arguments of the cached functions.

        **kwargs: Any
            Keyword arguments of the cached function.

        Example
        -------
        >>> import streamlit as st
        >>> import time
        >>>
        >>> @st.cache_data
        >>> def foo(bar):
        >>>     time.sleep(2)
        >>>     st.write(f"Executed foo({bar}).")
        >>>     return bar
        >>>
        >>> if st.button("Clear all cached values for `foo`", on_click=foo.clear):
        >>>     foo.clear()
        >>>
        >>> if st.button("Clear the cached value of `foo(1)`"):
        >>>     foo.clear(1)
        >>>
        >>> foo(1)
        >>> foo(2)

        """
        ...
    


