import { Command } from "./command";
import { MiddlewareStack } from "./middleware";
import { MetadataBearer } from "./response";

interface InvokeFunction<InputTypes extends object, OutputTypes extends MetadataBearer, ResolvedClientConfiguration> {
    <InputType extends InputTypes, OutputType extends OutputTypes>(command: Command<InputTypes, InputType, OutputTypes, OutputType, ResolvedClientConfiguration>, options?: any): Promise<OutputType>;
    <InputType extends InputTypes, OutputType extends OutputTypes>(command: Command<InputTypes, InputType, OutputTypes, OutputType, ResolvedClientConfiguration>, options: any, cb: (err: any, data?: OutputType) => void): void;
    <InputType extends InputTypes, OutputType extends OutputTypes>(command: Command<InputTypes, InputType, OutputTypes, OutputType, ResolvedClientConfiguration>, options?: any, cb?: (err: any, data?: OutputType) => void): Promise<OutputType> | void;
}

export interface Client<Input extends object, Output extends MetadataBearer, ResolvedClientConfiguration> {
    readonly config: ResolvedClientConfiguration;
    middlewareStack: MiddlewareStack<Input, Output>;
    send: InvokeFunction<Input, Output, ResolvedClientConfiguration>;
    destroy: () => void;
}
export {};
