import { WorkerLogLevel } from "@webda/workout";
import { EventEmitter } from "events";
import * as http from "http";
import sanitize from "sanitize-html";
import { Readable, Writable } from "stream";
import { Core } from "../core.js";
import { User } from "../models/user.js";
import { Service } from "../services/service.js";
import { Session } from "../utils/session.js";
import { HttpContext } from "./httpcontext.js";
/**
 * @category CoreFeatures
 */
declare class Cookie {
    name: string;
    value: string;
    options: any;
}
/**
 * Data provided by the context
 */
export interface ContextProviderInfo {
    /**
     * Stream to write to
     */
    stream?: Writable;
    /**
     * If this is http context
     */
    http?: HttpContext;
    /**
     * true if this is a global context
     */
    global?: boolean;
    /**
     * Can contain any type of information
     */
    [key: string]: any;
}
/**
 * @category CoreFeatures
 */
export interface ContextProvider {
    /**
     * Info can contain any type of information
     * @param info
     */
    getContext(info: ContextProviderInfo): OperationContext;
}
/**
 * OperationContext is used when call to an operation
 *
 * @param T type of input for this context
 * @param U type of output for this context
 */
export declare class OperationContext<T = any, U = any> extends EventEmitter {
    protected static __globalContext: OperationContext;
    /**
     * Contain emitting Core
     */
    protected _webda: Core;
    /**
     * Session
     */
    protected session: Session;
    /**
     * Allow extensions
     */
    protected extensions: {
        [key: string]: any;
    };
    /**
     * Contain the sanitized request body if computed
     */
    protected _sanitized: any;
    /**
     * Output
     */
    protected _body: string;
    /**
     * Loaded user if exist
     */
    private user;
    /**
     * Contain all registered promises to this context
     */
    _promises: Promise<any>[];
    /**
     * @ignore
     * Used by Webda framework to set the body, session and output stream if known
     */
    constructor(webda: Core, stream?: Writable);
    /**
     * Output stream
     */
    _stream: Writable;
    /**
     * Get an extension of the context
     * @param name of the extension
     * @returns extension object
     */
    getExtension<K = any>(name: string): K;
    /**
     * For easier compatibility with WebContext
     * On OperationContext this call is simply ignored
     */
    setHeader(_name: string, _value: string): void;
    /**
     * For easier compatibility with WebContext
     * On OperationContext this call is simply ignored
     */
    writeHead(_code: number, _headers: any): void;
    /**
     *
     * @param name to add
     * @param extension object to store
     */
    setExtension(name: string, extension: any): this;
    /**
     * Return the webda
     */
    getWebda(): Core<import("../core").CoreEvents>;
    /**
     * Register a promise with the context
     * @param promise
     */
    addAsyncRequest(promise: any): void;
    /**
     * Get output as string, if a OutputStream is provided it will returned null
     * @returns
     */
    getOutput(): string;
    /**
     * Get current http context
     */
    getHttpContext(): HttpContext | undefined;
    /**
     * Ensure the whole execution is finished
     */
    end(): Promise<void>;
    getInput(sanitizedOptions?: sanitize.IOptions & {
        defaultValue?: any;
        raw?: boolean | string[];
    }): Promise<T>;
    /**
     * By default empty
     * @returns
     */
    getRawInputAsString(limit?: number, timeout?: number, encoding?: BufferEncoding): Promise<string>;
    /**
     * @override
     */
    getRawInput(_limit?: number, _timeout?: number): Promise<Buffer>;
    /**
     * @override
     */
    getRawStream(): Readable;
    /**
     * Get the HTTP stream to output raw data
     * @returns {*}
     */
    getOutputStream(): Writable;
    /**
     * Get linked session
     * @returns
     */
    getSession<K = Session>(): K;
    /**
     * Remove sanitized body
     */
    reinit(): void;
    /**
     * Create a buffer stream
     */
    createStream(): void;
    /**
     * Proxy for simplification
     * @param level
     * @param args
     */
    log(level: WorkerLogLevel, ...args: any[]): void;
    /**
     * Create a new session
     * @returns
     */
    newSession(): Promise<Session>;
    /**
     * Remove everything that was about to be sent
     */
    resetResponse(): void;
    /**
     * Write data to the client
     *
     * @param output If it is an object it will be serialized with toPublicJSON, if it is a String it will be appended to the result, if it is a buffer it will replace the result
     * @param ...args any arguments to pass to the toPublicJSON method
     */
    write(output: U, _encoding?: string, _cb?: (error: Error) => void): boolean;
    init(): Promise<this>;
    /**
     * Get the current user from session
     */
    getCurrentUser<K extends User>(refresh?: boolean): Promise<K>;
    /**
     * Get the current user id from session
     */
    getCurrentUserId(): string;
    /**
     * Global context is the default Context
     *
     * Whenever a request is internal to the system
     * or not linked to a user request
     * @returns
     */
    isGlobal(): boolean;
}
export declare class GlobalContext extends OperationContext {
    session: Session;
    constructor(webda: Core);
    /**
     * @override
     */
    isGlobal(): boolean;
}
/**
 * Simple Operation Context with custom input
 */
export declare class SimpleOperationContext extends OperationContext {
    constructor(webda: Core);
    input: Buffer;
    /**
     * Create another context from an existing one
     * @param context
     * @returns
     */
    static fromContext(context: OperationContext): Promise<SimpleOperationContext>;
    /**
     * Set the input
     */
    setInput(input: Buffer): this;
    /**
     * Set the session
     * @param session
     * @returns
     */
    setSession(session: Session): this;
    /**
     * @override
     */
    getRawInput(limit?: number, _timeout?: number): Promise<Buffer>;
}
/**
 * This represent in fact a WebContext
 * In 3.0 an abstract version of Context will replace this (closer to OperationContext)
 * @category CoreFeatures
 *
 */
export declare class WebContext<T = any, U = any> extends OperationContext<T, U> {
    /**
     * Contains the response headers
     */
    protected _outputHeaders: http.OutgoingHttpHeaders;
    /**
     * Current status code
     */
    statusCode: number;
    /**
     * Cookies to send back
     */
    _cookie: Map<string, Cookie>;
    /**
     *
     */
    headers: Map<string, string>;
    _route: any;
    _ended: Promise<any>;
    _executor: Service<any>;
    /**
     * If headers were flushed
     */
    protected headersFlushed: boolean;
    protected parameters: any;
    protected _pathParams: any;
    protected _serviceParams: any;
    private _init;
    /**
     * Set current http context
     * @param httpContext current http context
     */
    setHttpContext(httpContext: HttpContext): void;
    /**
     * @override
     */
    getRawInputAsString(limit?: number, timeout?: number, encoding?: string): Promise<string>;
    /**
     * @override
     */
    getRawInput(limit?: number, timeout?: number): Promise<Buffer>;
    /**
     * @override
     */
    getRawStream(): Readable;
    /**
     * Get output headers
     */
    getResponseHeaders(): any;
    getRequestParameters(): any;
    parameter(name: string): any;
    getParameters(): any;
    private processParameters;
    getServiceParameters(): any;
    getPathParameters(): any;
    setServiceParameters(params: any): void;
    setPathParameters(params: any): void;
    /**
     * Remove everything that was about to be sent
     */
    resetResponse(): void;
    /**
     * Write data to the client
     *
     * @param output If it is an object it will be serializeb with toPublicJSON, if it is a String it will be appended to the result, if it is a buffer it will replace the result
     * @param ...args any arguments to pass to the toPublicJSON method
     */
    write(output: U, encoding?: string, cb?: (error: Error) => void): boolean;
    /**
     * Set a header value
     *
     * @param {String} header name
     * @param {String} value
     */
    setHeader(header: any, value: any): void;
    /**
     * Write the http return code and some headers
     * Those headers are not flushed yet so can still be overwritten
     *
     * @param {Number} statusCode to return to the client
     * @param {Object} headers to add to the response
     */
    writeHead(statusCode: number, headers?: http.OutgoingHttpHeaders): this;
    /**
     *
     * @returns
     */
    getResponseCode(): number;
    /**
     * Redirect to another url
     * @param url
     */
    redirect(url: string): void;
    /**
     * For compatibility reason
     */
    cookie(param: any, value: any, options?: any): void;
    getResponseCookies(): Map<string, Cookie>;
    isEnded(): Promise<any>;
    /******************************
     *
     * Express Compatibiliy method
     *
     ******************************/
    /**
     * Express response allow statusCode to be defined this way
     * @param code to return
     */
    status(code: number): this;
    /**
     * Express response allow answer to be sent this way
     * @param code to return
     */
    json(obj: any): this;
    /**
     * Return the response size
     * @returns
     */
    getResponseSize(): number | undefined;
    /**
     * Flush the request
     *
     * @emits 'finish' event
     * @throws Error if the request was already ended
     */
    end(): Promise<any>;
    /**
     * Alias to keep compatibility with WebContext
     * @param sanitizedOptions
     * @returns
     */
    getRequestBody(sanitizedOptions?: any): Promise<T>;
    /**
     * Get request body
     * @returns
     */
    getResponseBody(): string | false | Buffer;
    /**
     * Retrieve a http.IncomingMessage valid from Context
     *
     * Need more testing
     * @returns
     */
    getRequest(): http.IncomingMessage;
    /**
     * Get a service from webda
     *
     * @see Webda
     * @param {String} name of the service
     */
    getService<K extends Service>(name: any): K;
    /**
     * Get the HTTP stream to output raw data
     * @returns {*}
     */
    getStream(): Writable;
    /**
     * Get the current user id from session
     */
    getCurrentUserId(): string;
    /**
     * Return the service handling the request
     */
    getExecutor(): Service<any>;
    /**
     * Execute the target route
     */
    execute(): Promise<any>;
    /**
     * Get the request locale if found
     */
    getLocale(): string;
    /**
     * @ignore
     * Used by Webda framework to set the current route
     */
    setRoute(route: any): void;
    getRoute(): any;
    /**
     * @param executor {object} Set the current executor for this context
     */
    setExecutor(executor: any): void;
    /**
     * @ignore
     * Used for compatibility with express module
     */
    logIn(): void;
    /**
     * Return true if Headers got flushed already
     * @returns
     */
    hasFlushedHeaders(): boolean;
    /**
     * Set flushed header status
     * @param status
     */
    setFlushedHeaders(status?: boolean): void;
    /**
     * @ignore
     * Used by Webda framework to set the body, session and output stream if known
     */
    constructor(webda: Core, httpContext: HttpContext, stream?: Writable);
    init(force?: boolean): Promise<this>;
    emitError(err: any): void;
}
export {};
