import { AsyncTasksFlow, FlowTask, FlowTaskArgs, FlowOptions } from "taskset";

export type RouteHandlerArgs = FlowTaskArgs;

export type RouterHandler = FlowTask;

export type StaticResponse = {
  code?: Number;
  redirect?: string;
  headers?: {
    [key: string]: string;
  };
  body?: string | any;
};

export type RouteOptions = {
  path?: string | "*";
  method?: string | "*";
  response?: string | StaticResponse;
  handler?: RouterHandler | RouterHandler[];
  params?: {
    [key: string]: string;
  };
};

export type PathRule = {
  raw: string;
  flag: "r" | "^" | "=" | "*";
  value: string | RegExp;
  names: string[];
};
export type HttpMethod =
  | "GET"
  | "POST"
  | "PUT"
  | "DELETE"
  | "OPTIONS"
  | "HEAD"
  | "*";

export type Route = {
  path: PathRule;
  method: HttpMethod[];
  handler: RouterHandler[];
  params?: {
    [key: string]: string;
  };
};

export declare class RouteMatcher {
  routes: Route[];
  constructor(routes: RouteOptions[], defaultRoute?: RouteOptions);
  matchRoute(path: string, method: string): Route | void;
}

export type RouterOptions = RouteOptions &
  FlowOptions & {
    onRoute?: (route: Route, req: any, res: any) => void;
  };

export declare class ExpressRouter extends RouteMatcher {
  flow: AsyncTasksFlow;
  constructor(routes: RouteOptions[], routerOptions?: RouterOptions);
  matchHandlers(req: any, res: any): RouterHandler[] | void;
  handle(req: any, res: any): void;
}
