import type { HttpContext } from '@adonisjs/core/http';
import type { EmitterLike } from '@adonisjs/core/types/events';
import type { AccessToken } from './access_token.ts';
import type { AuthClientResponse, GuardContract } from '../../src/types.ts';
import { GUARD_KNOWN_EVENTS, type PROVIDER_REAL_USER } from '../../src/symbols.ts';
import type { AccessTokensGuardEvents, AccessTokensUserProviderContract } from './types.ts';
/**
 * Implementation of access tokens guard for the Auth layer. The heavy lifting
 * of verifying tokens is done by the user provider. However, the guard is
 * used to seamlessly integrate with the auth layer of the package.
 *
 * @template UserProvider - The user provider contract
 *
 * @example
 * const guard = new AccessTokensGuard(
 *   'api',
 *   ctx,
 *   emitter,
 *   userProvider
 * )
 *
 * const user = await guard.authenticate()
 * console.log('Authenticated user:', user.email)
 */
export declare class AccessTokensGuard<UserProvider extends AccessTokensUserProviderContract<unknown>> implements GuardContract<UserProvider[typeof PROVIDER_REAL_USER] & {
    currentAccessToken: AccessToken;
}> {
    #private;
    /**
     * Events emitted by the guard
     */
    [GUARD_KNOWN_EVENTS]: AccessTokensGuardEvents<UserProvider[typeof PROVIDER_REAL_USER] & {
        currentAccessToken: AccessToken;
    }>;
    /**
     * Driver name of the guard
     */
    driverName: 'access_tokens';
    /**
     * Whether or not the authentication has been attempted
     * during the current request.
     */
    authenticationAttempted: boolean;
    /**
     * A boolean to know if the current request has
     * been authenticated
     */
    isAuthenticated: boolean;
    /**
     * Reference to an instance of the authenticated user.
     * The value only exists after calling one of the
     * following methods.
     *
     * - authenticate
     * - check
     *
     * You can use the "getUserOrFail" method to throw an exception if
     * the request is not authenticated.
     */
    user?: UserProvider[typeof PROVIDER_REAL_USER] & {
        currentAccessToken: AccessToken;
    };
    /**
     * Creates a new AccessTokensGuard instance
     *
     * @param name - Unique name for the guard instance
     * @param ctx - HTTP context for the current request
     * @param emitter - Event emitter for guard events
     * @param userProvider - User provider for token verification
     *
     * @example
     * const guard = new AccessTokensGuard(
     *   'api',
     *   ctx,
     *   emitter,
     *   new TokenUserProvider()
     * )
     */
    constructor(name: string, ctx: HttpContext, emitter: EmitterLike<AccessTokensGuardEvents<UserProvider[typeof PROVIDER_REAL_USER] & {
        currentAccessToken: AccessToken;
    }>>, userProvider: UserProvider);
    /**
     * Returns an instance of the authenticated user. Or throws
     * an exception if the request is not authenticated.
     *
     * @throws {E_UNAUTHORIZED_ACCESS} When user is not authenticated
     *
     * @example
     * const user = guard.getUserOrFail()
     * console.log('User ID:', user.id)
     * console.log('Current token:', user.currentAccessToken.name)
     */
    getUserOrFail(): UserProvider[typeof PROVIDER_REAL_USER] & {
        currentAccessToken: AccessToken;
    };
    /**
     * Authenticate the current HTTP request by verifying the bearer
     * token or fails with an exception
     *
     * @throws {E_UNAUTHORIZED_ACCESS} When authentication fails
     *
     * @example
     * try {
     *   const user = await guard.authenticate()
     *   console.log('Authenticated as:', user.email)
     *   console.log('Token abilities:', user.currentAccessToken.abilities)
     * } catch (error) {
     *   console.log('Authentication failed')
     * }
     */
    authenticate(): Promise<UserProvider[typeof PROVIDER_REAL_USER] & {
        currentAccessToken: AccessToken;
    }>;
    /**
     * Create a token for a user (sign in)
     *
     * @param user - The user to create a token for
     * @param abilities - Optional array of abilities the token should have
     * @param options - Optional token configuration
     *
     * @example
     * const token = await guard.createToken(user, ['read', 'write'], {
     *   name: 'Mobile App',
     *   expiresIn: '7d'
     * })
     * console.log('Token:', token.value.release())
     */
    createToken(user: UserProvider[typeof PROVIDER_REAL_USER], abilities?: string[], options?: {
        expiresIn?: string | number;
        name?: string;
    }): Promise<AccessToken>;
    /**
     * Invalidates the currently authenticated token (sign out)
     *
     * @example
     * await guard.invalidateToken()
     * console.log('Token invalidated successfully')
     */
    invalidateToken(): Promise<boolean>;
    /**
     * Returns the Authorization header clients can use to authenticate
     * the request.
     *
     * @param user - The user to authenticate as
     * @param abilities - Optional array of abilities
     * @param options - Optional token configuration
     *
     * @example
     * const clientAuth = await guard.authenticateAsClient(user, ['read'])
     * // Use clientAuth.headers.authorization in API tests
     */
    authenticateAsClient(user: UserProvider[typeof PROVIDER_REAL_USER], abilities?: string[], options?: {
        expiresIn?: string | number;
        name?: string;
    }): Promise<AuthClientResponse>;
    /**
     * Silently check if the user is authenticated or not. The
     * method is same as the "authenticate" method but does not
     * throw any exceptions.
     *
     * @example
     * const isAuthenticated = await guard.check()
     * if (isAuthenticated) {
     *   const user = guard.user
     *   console.log('User is authenticated:', user.email)
     * }
     */
    check(): Promise<boolean>;
}
