import { LoadPath, HTTPMethods, RoutedValidation, MiddlewareInitted } from "../../types/internal";
import Static from "../../types/static";
import HTTP from "../../types/http";
import WebSocket from "../../types/webSocket";
import { Content } from "../..";
import RouteWS from "./ws";
import RouteHTTP from "./http";
import RouteDefaultHeaders from "./defaultHeaders";
export default class RoutePath<GlobContext extends Record<any, any>, Middlewares extends MiddlewareInitted[] = [], Path extends string = '/'> {
    private externals;
    private validations;
    private headers;
    private parsedHeaders;
    private loadPaths;
    private statics;
    private routes;
    private webSockets;
    private httpPath;
    private hasCalledGet;
    /** Generate Route Block */
    constructor(
    /** The Path of the Routes */ path: Path, 
    /** The Validations to add */ validations?: RoutedValidation[], 
    /** The Headers to add */ headers?: Record<string, Content>, 
    /** The Contexts to add */ contexts?: HTTP['context']);
    /**
     * Add a Validation
     * @example
     * ```
     * // The /api route will automatically check for correct credentials
     * // Obviously still putting the prefix (in this case / from the RoutePath in front)
     * const controller = new Server({ })
     *
     * controller.path('/api', (path) => path
     *   .validate(async(ctr, end) => {
     *     if (!ctr.headers.has('Authorization')) return end(ctr.status(401).print('Unauthorized'))
     *     if (ctr.headers.get('Authorization') !== 'key123 or db request ig') return end(ctr.status(401).print('Unauthorized'))
     *   })
     *   .redirect('/pics', 'https://google.com/search?q=devil')
     * )
     * ```
     * @since 3.2.1
    */ validate<Context extends Record<any, any> = {}, Body = unknown>(
    /** The Function to Validate the Request */ code: RoutedValidation<GlobContext & Context, Body, Middlewares, Path>): this;
    /**
     * Add a HTTP Route
     * @example
     * ```
     * controller.path('/', (path) => path
     *   .http('GET', '/hello', (ws) => ws
     *     .onRequest(async(ctr) => {
     *       ctr.print('Hello bro!')
     *     })
     *   )
     * )
     * ```
     * @since 6.0.0
    */ http<Context extends Record<any, any> = {}, Body = unknown, LPath extends string = '/'>(
    /** The Request Method */ method: HTTPMethods, 
    /** The Path on which this will be available */ path: LPath | RegExp, 
    /** The Callback to handle the Endpoint */ callback: (path: RouteHTTP<GlobContext, Context, Body, Middlewares, `${Path}/${LPath}`>) => RouteHTTP<GlobContext, Context, Body, Middlewares, `${Path}/${LPath}`>): this;
    /**
     * Add a Websocket Route
     * @example
     * ```
     * controller.path('/', (path) => path
     *   .ws('/uptime', (ws) => ws
     *     .onConnect(async(ctr) => {
     *       console.log('Connected to ws!')
     *     })
     * 		.onMessage((ctr) => {
     *      console.log('Received message', ctr.message)
     *    })
     *    .onClose((ctr) => {
     *      console.log('Disconnected from ws!')
     *    })
     *   )
     * )
     * ```
     * @since 5.4.0
    */ ws<Context extends Record<any, any> = {}, Message = unknown, LPath extends string = '/'>(
    /** The Path on which this will be available */ path: LPath | RegExp, 
    /** The Callback to handle the Endpoint */ callback: (path: RouteWS<GlobContext, Context, Message, Middlewares, `${Path}/${LPath}`>) => RouteWS<GlobContext, Context, Message, Middlewares, `${Path}/${LPath}`>): this;
    /**
     * Add Default Headers
     * @example
     * ```
     * controller.path('/', (path) => path
     *   .defaultHeaders((dH) => dH
     *     .add('X-Api-Version', '1.0.0')
     *   )
     * )
     * ```
     * @since 6.0.0
    */ defaultHeaders(
    /** The Callback to handle the Headers */ callback: (path: RouteDefaultHeaders) => RouteDefaultHeaders): this;
    /**
     * Add a Redirect
     * @example
     * ```
     * // The /devil route will automatically redirect to google.com
     * // Obviously still putting the prefix (in this case / from the RoutePath in front)
     * const controller = new Server({ })
     *
     * controller.path('/', (path) => path
     *   .redirect('/devil', 'https://google.com')
     *   .redirect('/devilpics', 'https://google.com/search?q=devil')
     * )
     * ```
     * @since 3.1.0
    */ redirect(
    /** The Request Path to Trigger the Redirect on */ request: string, 
    /** The Redirect Path to Redirect to */ redirect: string): this;
    /**
     * Serve Static Files
     * @example
     * ```
     * // All Files in "./static" will be served dynamically so they wont be loaded as routes by default
     * // Due to the hideHTML Option being on files will be served differently, /index.html -> /; /about.html -> /about; /contributors/index.html -> /contributors
     * const controller = new Server({ })
     *
     * controller.path('/', (path) => path
     *   .static('./static', {
     *     hideHTML: true, // If enabled will remove .html ending from files
     *     addTypes: true, // If enabled will automatically add content-types to some file endings (including the custom ones defined in the main config)
     *   })
     * )
     * ```
     * @since 3.1.0
    */ static(
    /** The Folder which will be used */ folder: string, 
    /** Additional Configuration for Serving */ options?: {
        /**
         * Whether to automatically add Content-Type to some file endings
         * @default true
         * @since 3.1.0
        */ addTypes?: boolean;
        /**
         * Whether to compress files when sending
         * @default true
         * @since 7.10.0
        */ compress?: boolean;
        /**
         * Whether to automatically remove .html ending from files
         * @default false
         * @since 3.1.0
        */ hideHTML?: boolean;
    }): this;
    /**
     * Load CJS Route Files
     * @example
     * ```
     * // All Files in "./routes" ending with .js will be loaded as routes
     * const controller = new Server({ })
     *
     * controller.path('/', (path) => path
     *   .loadCJS('./routes')
     * )
     * ```
     * @since 3.1.0
    */ loadCJS(
    /** The Folder which will be used */ folder: string, 
    /** The Options */ options?: {
        /**
         * Whether to enable file based routing, works similarly to static file hideHTML
         * @default false
         * @since 7.5.0
        */ fileBasedRouting?: boolean;
    }): this;
    /**
     * Load ESM Route Files
     * @example
     * ```
     * // All Files in "./routes" ending with .js will be loaded as routes
     * const controller = new Server({ })
     *
     * controller.path('/', (path) => path
     *   .loadESM('./routes')
     * )
     * ```
     * @since 4.0.0
    */ loadESM(
    /** The Folder which will be used */ folder: string, 
    /** The Options */ options?: {
        /**
         * Whether to enable file based routing, works similarly to static file hideHTML
         * @default false
         * @since 7.5.0
        */ fileBasedRouting?: boolean;
    }): this;
    /**
     * Add a new Block of Routes with a Prefix
     * @example
     * ```
     * const controller = new Server({ })
     *
     * controller.path('/', (path) => path
     *   .http('GET', '/cool', (http) => http
     *     .onRequest((ctr) => {
     *       ctr.print('cool!')
     *     })
     *   )
     *   .path('/api', (path) => path
     *     .context({
     *       version: '1.0.0'
     *     })
     *     .http('GET', '/', (http) => http
     *       .onRequest((ctr) => {
     *         ctr.print(`Welcome to the API!, Version ${ctr["@"].version}`)
     *       })
     *     )
     *   )
     * )
     * ```
     * @since 5.0.0
    */ path<LPath extends string = `/${string}`>(
    /** The Path Prefix */ prefix: LPath, 
    /** The Callback to handle the Prefix */ router: ((path: RoutePath<GlobContext, Middlewares, `${Path}/${LPath}`>) => RoutePath<GlobContext, Middlewares, `${Path}/${LPath}`>) | RoutePath<any, any>): this;
    /**
     * Internal Method for Generating Routes Object
     * @since 6.0.0
    */ getData(): Promise<{
        routes: HTTP[];
        webSockets: WebSocket[];
        statics: Static[];
        loadPaths: LoadPath[];
    }>;
}
