import { Application } from '@lunoxjs/core';
import { Request, Class } from '@lunoxjs/core/contracts';

interface UserProviderConfig {
    driver: string;
    [key: string]: any;
}
interface GuardConfig {
    driver: string;
    provider: string;
    remember?: number;
}
interface AuthConfig {
    defaults: {
        guard: string;
    };
    guards: Record<string, GuardConfig>;
    providers: Record<string, UserProviderConfig>;
}

interface Authenticatable {
    getAuthIdentifierName(): string;
    getAuthPassword(): string;
    getAuthIdentifier(): string;
    /**
     * Get the token value for the "remember me" session.
     */
    getRememberToken(): string;
    /**
     * Get the column name for the "remember me" token.
     */
    getRememberTokenName(): string;
    /**
     * Set the token value for the "remember me" session.
     */
    setRememberToken(token: string): void;
}
interface Credentials {
    password?: string;
    [key: string]: any;
}

interface Guard {
    check(): Promise<boolean>;
    guest(): Promise<boolean>;
    user<T = Authenticatable>(): Promise<T | undefined>;
    id(): Promise<string | undefined>;
    validate(credentials: Credentials): Promise<boolean>;
    setUser(user: Authenticatable): void;
}

interface StatefulGuard extends Guard {
    attempt: (credentials: Credentials, remember?: boolean) => Promise<boolean>;
    login(user: Authenticatable, remember?: boolean): Promise<void>;
    logout(): Promise<void>;
}

interface UserProvider {
    validateCredentials(user: Authenticatable, credentials: Credentials): boolean;
    retrieveByCredentials(credentials: Credentials): Promise<Authenticatable | undefined>;
    retrieveById(id: string): Promise<Authenticatable | undefined>;
    /**
     * Update the "remember me" token for the given user in storage.
     */
    updateRememberToken(user: Authenticatable, token: string): Promise<void>;
    /**
     * Retrieve a user by their unique identifier and "remember me" token.
     */
    retrieveByToken(identifier: any, token: string): Promise<Authenticatable | undefined>;
}

type DriverCreator = (name: string, config: GuardConfig) => Guard;
type UserProviderCreator = (config: UserProviderConfig) => UserProvider;
declare class AuthManager {
    static symbol: symbol;
    protected static drivers: Record<string, DriverCreator>;
    protected static userProviders: Record<string, UserProviderCreator>;
    protected app: Application;
    protected guards: Record<string, Guard>;
    protected request: Request;
    constructor(app: Application);
    static registerUserProvider(name: string, providerCreator: UserProviderCreator): void;
    static registerDriver(name: string, driverCreator: DriverCreator): void;
    setRequest(request: Request): this;
    getRequest(): Request;
    guard(name?: string): Guard;
    getDefaultDriver(): string;
    protected resolve(name: string): Guard;
    static createDriver(name: string, config: GuardConfig): Guard;
    static createUserProvider(provider: string): UserProvider;
    protected getConfig(name: string): GuardConfig;
    protected static getProviderConfiguration(provider?: string): UserProviderConfig | undefined;
    static getDefaultUserProvider(): string;
    __get(method: keyof StatefulGuard): any;
}
declare const _default: typeof AuthManager & Class<StatefulGuard, any[]>;

export { AuthManager as A, Credentials as C, Guard as G, StatefulGuard as S, UserProvider as U, _default as _, Authenticatable as a, UserProviderConfig as b, GuardConfig as c, AuthConfig as d };
