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

from typing import Any, Protocol, TypeVar

from flask import Flask, Response

A = TypeVar("A", covariant=True)
class UserMixinProtocol(Protocol[A]):
    @property
    def is_active(self) -> bool: ...

    @property
    def is_authenticated(self) -> bool: ...

    @property
    def is_anonymous(self) -> bool: ...

    def get_id(self) -> str: ...

TUserMixin = TypeVar("TUserMixin", bound=UserMixinProtocol[Any], covariant=True)

class UserLoaderCallback(Protocol[TUserMixin]):
    def __call__(self, username: str) -> TUserMixin | None:
        ...


class LoginManager:
    """This object is used to hold the settings used for logging in. Instances
    of :class:`LoginManager` are *not* bound to specific apps, so you can
    create one in the main body of your code and then bind it to your
    app in a factory function.
    """
    def __init__(self, app=..., add_context_processor=...) -> None:
        ...
    
    def setup_app(self, app, add_context_processor=...) -> None:
        """
        This method has been deprecated. Please use
        :meth:`LoginManager.init_app` instead.
        """
        ...
    
    def init_app(self, app: Flask, add_context_processor: bool=True) -> None:
        """
        Configures an application. This registers an `after_request` call, and
        attaches this `LoginManager` to it as `app.login_manager`.

        :param app: The :class:`flask.Flask` object to configure.
        :type app: :class:`flask.Flask`
        :param add_context_processor: Whether to add a context processor to
            the app that adds a `current_user` variable to the template.
            Defaults to ``True``.
        :type add_context_processor: bool
        """
        ...
    
    def unauthorized(self) -> Response:
        """
        This is called when the user is required to log in. If you register a
        callback with :meth:`LoginManager.unauthorized_handler`, then it will
        be called. Otherwise, it will take the following actions:

            - Flash :attr:`LoginManager.login_message` to the user.

            - If the app is using blueprints find the login view for
              the current blueprint using `blueprint_login_views`. If the app
              is not using blueprints or the login view for the current
              blueprint is not specified use the value of `login_view`.

            - Redirect the user to the login view. (The page they were
              attempting to access will be passed in the ``next`` query
              string variable, so you can redirect there if present instead
              of the homepage. Alternatively, it will be added to the session
              as ``next`` if USE_SESSION_FOR_NEXT is set.)

        If :attr:`LoginManager.login_view` is not defined, then it will simply
        raise a HTTP 401 (Unauthorized) error instead.

        This should be returned from a view or before/after_request function,
        otherwise the redirect will have no effect.
        """
        ...
    
    def user_loader(self, callback: UserLoaderCallback[A]) -> UserLoaderCallback[A]:
        """
        This sets the callback for reloading a user from the session. The
        function you set should take a user ID (a ``str``) and return a
        user object, or ``None`` if the user does not exist.

        :param callback: The callback for retrieving a user object.
        :type callback: callable
        """
        ...
    
    @property
    def user_callback(self) -> UserLoaderCallback[A]:
        """Gets the user_loader callback set by user_loader decorator."""
        ...
    
    def request_loader(self, callback): # -> None:
        """
        This sets the callback for loading a user from a Flask request.
        The function you set should take Flask request object and
        return a user object, or `None` if the user does not exist.

        :param callback: The callback for retrieving a user object.
        :type callback: callable
        """
        ...
    
    @property
    def request_callback(self): # -> None:
        """Gets the request_loader callback set by request_loader decorator."""
        ...
    
    def unauthorized_handler(self, callback):
        """
        This will set the callback for the `unauthorized` method, which among
        other things is used by `login_required`. It takes no arguments, and
        should return a response to be sent to the user instead of their
        normal view.

        :param callback: The callback for unauthorized users.
        :type callback: callable
        """
        ...
    
    def needs_refresh_handler(self, callback):
        """
        This will set the callback for the `needs_refresh` method, which among
        other things is used by `fresh_login_required`. It takes no arguments,
        and should return a response to be sent to the user instead of their
        normal view.

        :param callback: The callback for unauthorized users.
        :type callback: callable
        """
        ...
    
    def needs_refresh(self): # -> Response:
        """
        This is called when the user is logged in, but they need to be
        reauthenticated because their session is stale. If you register a
        callback with `needs_refresh_handler`, then it will be called.
        Otherwise, it will take the following actions:

            - Flash :attr:`LoginManager.needs_refresh_message` to the user.

            - Redirect the user to :attr:`LoginManager.refresh_view`. (The page
              they were attempting to access will be passed in the ``next``
              query string variable, so you can redirect there if present
              instead of the homepage.)

        If :attr:`LoginManager.refresh_view` is not defined, then it will
        simply raise a HTTP 401 (Unauthorized) error instead.

        This should be returned from a view or before/after_request function,
        otherwise the redirect will have no effect.
        """
        ...
    
    def header_loader(self, callback):
        """
        This function has been deprecated. Please use
        :meth:`LoginManager.request_loader` instead.

        This sets the callback for loading a user from a header value.
        The function you set should take an authentication token and
        return a user object, or `None` if the user does not exist.

        :param callback: The callback for retrieving a user object.
        :type callback: callable
        """
        ...
    


