import {RequestHandler, Request, Response, NextFunction} from 'express-serve-static-core';

export default function middleware(opts: expacl.ACLOptions): expacl.Middleware;

declare namespace expacl {
    export type Any = '*'
    export type Method = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'
    export type Action = 'allow' | 'deny'

    interface MiddlewareHandler extends RequestHandler {
    }

    export type Middleware = MiddlewareHandler;

    export type MiddlewareFactory = (opts: expacl.ACLOptions) => Middleware

    export interface ACLRoute {
        path: string | object,
        roles?: Any | string | string[],
        methods?: Any | Method | Method[],
        subroutes?: ACLRoute[] | undefined,
        transient?: boolean,
        action?: Action,
    }

    interface ACLParsedRoute {
        path: (string | object)[],
        pathLen: number,
        roles: string[],
        methods: (Any | Method)[],
        action: Action,
    }

    interface ACLOptions {
        resource?: (req: ACLRequest) => string,
        roles?: (req: ACLRequest) => string[] | undefined,
        authenticated?: (req: ACLRequest) => boolean,
        routes: ACLRoute[],
        missingRoute?: Action,
        defaultAction?: Action,
        onNotAuthenticated?: (req: ACLRequest, res: Response, next: NextFunction) => any
        onNotAuthorized?: (req: ACLRequest, res: Response, next: NextFunction) => any
        onNotFound?: (req: ACLRequest, res: Response, next: NextFunction) => any
    }

    interface ACLRequest extends Request {
        user: any
    }
}

