import Route from "../Route";
import { Method } from "../../types/global";
import Http from "./Http";
import { UsableMiddleware } from "../Middleware";
import { UsableValidator } from "../Validator";
import { RateLimitConfig } from "../../types/internal";
import RateLimit from "./RateLimit";
import GlobalContext from "../../types/internal/classes/GlobalContext";
import { ArrayOrNot } from "@rjweb/utils";
import Ws from "./Ws";
import { OperationObject } from "openapi3-ts/oas31";
export default class Path<Middlewares extends UsableMiddleware[], Validators extends UsableValidator[] = [], Context extends Record<string, any> = {}, Excluded extends (keyof Path<Middlewares>)[] = []> {
    private validators;
    protected routesHttp: Route<'http'>[];
    protected routesStatic: Route<'static'>[];
    protected routesWS: Route<'ws'>[];
    protected _httpRatelimit: RateLimitConfig;
    protected _wsRatelimit: RateLimitConfig;
    protected promises: Promise<any>[];
    protected openApi: OperationObject;
    private _global;
    private prefix;
    private computePath;
    /**
     * Create a new Path
     * @since 6.0.0
    */ constructor(prefix: string, global: GlobalContext, validators?: Validators, ratelimits?: [RateLimitConfig, RateLimitConfig], promises?: Promise<any>[], openApi?: OperationObject);
    /**
     * Add OpenAPI Documentation to all HTTP Endpoints in this Path (and all children)
     * @since 9.0.0
    */ document(item: OperationObject): Omit<Path<Middlewares, Validators, Context, [...Excluded, 'document']>, Excluded[number] | 'document'>;
    /**
     * Add a Ratelimit to all HTTP Endpoints in this Path (and all children)
     *
     * When a User requests an Endpoint, that will count against their hit count, if
     * the hits exceeds the `<maxHits>` in `<timeWindow>ms`, they wont be able to access
     * the route for `<penalty>ms`.
     * @example
     * ```
     * import { time } from "@rjweb/utils"
     *
     * server.path('/', (path) => path
     *   .httpRateLimit((limit) => limit
     *     .hits(5)
     *     .window(time(20).s())
     *     .penalty(0)
     *   ) // This will allow 5 requests every 20 seconds
     *   .http('GET', '/hello', (ws) => ws
     *     .onRequest(async(ctr) => {
     *       ctr.print('Hello bro!')
     *     })
     *   )
     * )
     *
     * server.rateLimit('httpRequest', (ctr) => {
     *   ctr.print(`Please wait ${ctr.getRateLimit()?.resetIn}ms!!!!!`)
     * })
     * ```
     * @since 8.6.0
    */ httpRatelimit(callback: (limit: RateLimit) => any): Omit<Path<Middlewares, Validators, Context, Excluded>, Excluded[number] | 'httpRatelimit'>;
    /**
     * Add a Ratelimit to all WebSocket Endpoints in this Path (and all children)
     *
     * When a User sends a message to a Socket, that will count against their hit count, if
     * the hits exceeds the `<maxHits>` in `<timeWindow>ms`, they wont be able to access
     * the route for `<penalty>ms`.
     * @example
     * ```
     * import { time } from "@rjweb/utils"
     *
     * server.path('/', (path) => path
     *   .httpRateLimit((limit) => limit
     *     .hits(5)
     *     .window(time(20).s())
     *     .penalty(0)
     *   ) // This will allow 5 messages every 20 seconds
     *   .ws('/echo', (ws) => ws
     *     .onMessage(async(ctr) => {
     *       ctr.print(await ctr.rawMessageBytes())
     *     })
     *   )
     * )
     *
     * server.rateLimit('wsMessage', (ctr) => {
     *   ctr.print(`Please wait ${ctr.getRateLimit()?.resetIn}ms!!!!!`)
     * })
     * ```
     * @since 8.6.0
    */ wsRatelimit(callback: (limit: RateLimit) => any): Omit<Path<Middlewares, Validators, Context, Excluded>, Excluded[number] | 'wsRatelimit'>;
    /**
     * Create a redirection route
     * @example
     * ```
     * const server = new Server(...)
     *
     * server.path('/', (path) => path
     *   .redirect('/google', 'https://google.com')
     * )
     * ```
     * @since 3.10.0
    */ redirect(path: ArrayOrNot<string | RegExp>, redirect: string, type?: 'temporary' | 'permanent'): this;
    /**
     * Create a subpath of this Path
     * @since 6.0.0
    */ path(prefix: string, callback: (path: Path<Middlewares, Validators, Context>) => any): this;
    /**
     * Use a Validator on all Endpoints in this Path
     *
     * This will attach a Validator to all Endpoints in this Path
     * @since 9.0.0
    */ validate<_Validator extends UsableValidator<any>>(validator: _Validator): Path<Middlewares, [...Validators, _Validator], Context, Excluded>;
    /**
     * Serve Static Files
     * @example
     * ```
     * // All Files in "./public" will be served dynamically so they wont be loaded as routes by default
     * // Due to the stripHtmlEnding Option being on files will be served differently, /index.html -> /; /about.html -> /about; /contributors/index.html -> /contributors
     * const server = new Server(...)
     *
     * server.path('/', (path) => path
     *   .static('./public', {
     *     stripHtmlEnding: true // If enabled will remove .html ending from files
     *   })
     * )
     * ```
     * @since 3.1.0
    */ static(folder: string, options?: {
        /**
         * Whether to automatically remove .html ending from files
         * @default false
         * @since 9.0.0
        */ stripHtmlEnding?: boolean;
        /**
         * Whether to pre-process the files before serving them,
         * this will force you to restart the server every time
         * you add or remove a file.
         * @warning THIS WILL RECURSIVELY WALK THROUGH ALL FILES IN THE FOLDER, USE WITH CAUTION
         * @default false
         * @since 9.0.0
        */ preProcessFiles?: boolean;
    }): this;
    /**
     * Add a new HTTP Route
     * @example
     * ```
     * const server = new Server(...)
     *
     * server.path('/', (path) => path
     *   .http('GET', '/hello', (ws) => ws
     *     .onRequest((ctr) => {
     *       ctr.print('Hello!')
     *     })
     *   )
     * )
     * ```
     * @since 6.0.0
    */ http<_Method extends Method>(method: _Method, path: ArrayOrNot<string | RegExp>, callback: (http: Http<_Method, Middlewares, Validators, Context>) => any): this;
    /**
     * Add a new WebSocket Route
     * @example
     * ```
     * const server = new Server(...)
     *
     * server.path('/', (path) => path
     *   .ws('/echo', (ws) => ws
     *     .onMessage((ctr) => {
     *       ctr.print(ctr.rawMessageBytes())
     *     })
     *   )
     * )
     * ```
     * @since 6.0.0
    */ ws(path: ArrayOrNot<string | RegExp>, callback: (ws: Ws<Middlewares, Validators, Context>) => any): this;
}
