import { AsyncSeriesBailHook } from 'tapable';
import { AsyncSeriesHook } from 'tapable';
import { AsyncSeriesWaterfallHook } from 'tapable';
import { CustomHeaders } from '@oazapfts/runtime';
import { default as default_2 } from 'typescript';
import { InterfaceDeclaration } from 'typescript';
import { OpenAPIV3 } from 'openapi-types';
import { OpenAPIV3_1 } from 'openapi-types';
import { Statement } from 'typescript';
import { SyncWaterfallHook } from 'tapable';
import { TypeAliasDeclaration } from 'typescript';
import { TypeReferenceNode } from 'typescript';
import { UnsetAdditionalOptions } from 'tapable';

declare type ArgumentStyle = (typeof argumentStyleOptions)[number];

declare const argumentStyleOptions: readonly ["positional", "object"];

declare type DefaultImport = [string, {
    from: string;
}];

declare type DefaultImport_2 = [string, {
    from: string;
}];

declare type Defaults = {
    baseUrl?: string;
    headers?: CustomHeaders;
    FormData?: default_2.ClassExpression | default_2.Identifier;
    fetch?: default_2.FunctionExpression | default_2.ArrowFunction | default_2.Identifier;
};

declare type Defaults_2 = {
    baseUrl?: string;
    headers?: CustomHeaders;
    FormData?: default_2.ClassExpression | default_2.Identifier;
    fetch?: default_2.FunctionExpression | default_2.ArrowFunction | default_2.Identifier;
};

declare type DiscriminatorObject = OpenAPIV3.DiscriminatorObject | OpenAPIV3_1.DiscriminatorObject;

declare type Document_2 = OpenAPIV3.Document | OpenAPIV3_1.Document;

declare type Document_3 = OpenAPIV3.Document | OpenAPIV3_1.Document;

declare type EnumStyle = (typeof enumStyleOptions)[number];

declare const enumStyleOptions: readonly ["union", "enum", "as-const"];

declare type HttpMethod = (typeof HttpMethods)[number];

declare type HttpMethod_2 = (typeof HttpMethods_2)[number];

declare const HttpMethods: readonly ["GET", "PUT", "POST", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"];

declare const HttpMethods_2: readonly ["GET", "PUT", "POST", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"];

declare type Import = string | ImportsWithoutDefault | DefaultImport | ImportWithDefault | NamespaceImport;

declare type Import_2 = string | ImportsWithoutDefault_2 | DefaultImport_2 | ImportWithDefault_2 | NamespaceImport_2;

declare type ImportSpecifier = {
    name: string;
    as?: string;
};

declare type ImportSpecifier_2 = {
    name: string;
    as?: string;
};

declare type ImportsWithoutDefault = [
(ImportSpecifier | string)[],
    {
    from: string;
}
];

declare type ImportsWithoutDefault_2 = [
(ImportSpecifier_2 | string)[],
    {
    from: string;
}
];

declare type ImportWithDefault = [
string,
(ImportSpecifier | string)[],
    {
    from: string;
}
];

declare type ImportWithDefault_2 = [
string,
(ImportSpecifier_2 | string)[],
    {
    from: string;
}
];

declare type MediaTypeObject = OpenAPIV3.MediaTypeObject | OpenAPIV3_1.MediaTypeObject;

declare type NamespaceImport = [{
    namespace: string;
}, {
    from: string;
}];

declare type NamespaceImport_2 = [{
    namespace: string;
}, {
    from: string;
}];

declare type OazapftsContext = {
    readonly opts: ReadonlyDeep<OazapftsOptions>;
    readonly spec: Document_3;
    readonly mode?: OnlyMode_2;
    /** Banner comment at the top of the file (the text content, not including comment markers) */
    banner: string;
    /** Import declarations (AST nodes) */
    imports: Import_2[];
    /** Runtime defaults (baseUrl, etc.) - will be generated as `export const defaults = { ... }` */
    defaults: Defaults_2;
    /** Server definitions - will be generated as `export const servers = { ... }` */
    servers: ServerObject_2[];
    /** Initialization statements (e.g., `const oazapfts = Oazapfts.runtime(defaults)`) */
    init: Statement[];
    discriminatingSchemas: Set<SchemaObject_2>;
    aliases: (TypeAliasDeclaration | InterfaceDeclaration)[];
    enumAliases: Statement[];
    enumRefs: Record<string, {
        values: string;
        type: TypeReferenceNode;
    }>;
    refs: Record<string, {
        base: TypeReferenceNode;
        readOnly?: TypeReferenceNode;
        writeOnly?: TypeReferenceNode;
    }>;
    refsOnlyMode: Map<string, OnlyModes_2>;
    typeAliases: Record<string, number>;
    operationNames: Map<string, number>;
};

declare type OazapftsContext_2 = {
    readonly opts: ReadonlyDeep_2<OazapftsOptions>;
    readonly spec: Document_2;
    readonly mode?: OnlyMode;
    /** Banner comment at the top of the file (the text content, not including comment markers) */
    banner: string;
    /** Import declarations (AST nodes) */
    imports: Import[];
    /** Runtime defaults (baseUrl, etc.) - will be generated as `export const defaults = { ... }` */
    defaults: Defaults;
    /** Server definitions - will be generated as `export const servers = { ... }` */
    servers: ServerObject[];
    /** Initialization statements (e.g., `const oazapfts = Oazapfts.runtime(defaults)`) */
    init: Statement[];
    discriminatingSchemas: Set<SchemaObject>;
    aliases: (TypeAliasDeclaration | InterfaceDeclaration)[];
    enumAliases: Statement[];
    enumRefs: Record<string, {
        values: string;
        type: TypeReferenceNode;
    }>;
    refs: Record<string, {
        base: TypeReferenceNode;
        readOnly?: TypeReferenceNode;
        writeOnly?: TypeReferenceNode;
    }>;
    refsOnlyMode: Map<string, OnlyModes>;
    typeAliases: Record<string, number>;
    operationNames: Map<string, number>;
};

declare type OazapftsOptions = {
    include?: string[];
    exclude?: string[];
    optimistic?: boolean;
    unionUndefined?: boolean;
    /**
     * @deprecated Use `enumStyle: "enum"` instead.
     */
    useEnumType?: boolean;
    /**
     * Controls how enums are generated in TypeScript.
     * Takes precedence over `useEnumType` if both are specified.
     */
    enumStyle?: EnumStyle;
    mergeReadWriteOnly?: boolean;
    useUnknown?: boolean;
    argumentStyle?: ArgumentStyle;
    allSchemas?: boolean;
    /**
     * When true, serialize boolean query parameters as 1/0.
     */
    numericBooleanQueryParameters?: boolean;
    /**
     * When true, skip generating deprecated legacy method aliases for backward
     * compatibility. Only the primary normalized operationId-based names will
     * be generated.
     */
    futureStripLegacyMethods?: boolean;
    /**
     * Plugins to apply during code generation.
     * Each plugin receives hooks and can tap into generation steps.
     */
    UNSTABLE_plugins?: UNSTABLE_OazapftsPlugin_2[];
};

declare type OnlyMode = "readOnly" | "writeOnly";

declare type OnlyMode_2 = "readOnly" | "writeOnly";

declare type OnlyModes = Record<OnlyMode, boolean>;

declare type OnlyModes_2 = Record<OnlyMode_2, boolean>;

declare namespace OpenAPI {
        {
        SchemaObject,
        UNSTABLE_DiscriminatingSchemaObject,
        ReferenceObject,
        ParameterObject,
        Document_2 as Document,
        DiscriminatorObject,
        ResponseObject,
        ResponsesObject,
        RequestBodyObject,
        MediaTypeObject,
        OperationObject,
        PathsObject,
        PathItemObject,
        ServerObject
    }
}

declare namespace OpenApi {
    export {
        SchemaObject_2 as SchemaObject,
        UNSTABLE_DiscriminatingSchemaObject,
        ReferenceObject,
        ParameterObject,
        Document_3 as Document,
        DiscriminatorObject,
        ResponseObject,
        ResponsesObject,
        RequestBodyObject,
        MediaTypeObject,
        OperationObject,
        PathsObject,
        PathItemObject,
        ServerObject_2 as ServerObject
    }
}

declare type OperationObject = OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject;

declare type ParameterObject = OpenAPIV3.ParameterObject | OpenAPIV3_1.ParameterObject;

declare type PathItemObject = OpenAPIV3.PathItemObject | OpenAPIV3_1.PathItemObject;

declare type PathsObject = OpenAPIV3.PathsObject | OpenAPIV3_1.PathsObject;

declare type ReadonlyDeep<T> = {
    readonly [P in keyof T]: ReadonlyDeep<T[P]>;
};

declare type ReadonlyDeep_2<T> = {
    readonly [P in keyof T]: ReadonlyDeep_2<T[P]>;
};

declare type ReferenceObject = OpenAPIV3.ReferenceObject | OpenAPIV3_1.ReferenceObject;

declare type RequestBodyObject = OpenAPIV3.RequestBodyObject | OpenAPIV3_1.RequestBodyObject;

declare type ResponseObject = OpenAPIV3.ResponseObject | OpenAPIV3_1.ResponseObject;

declare type ResponsesObject = OpenAPIV3.ResponsesObject | OpenAPIV3_1.ResponsesObject;

declare type SchemaObject = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject | boolean;

declare type SchemaObject_2 = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject | boolean;

declare type ServerObject = OpenAPIV3.ServerObject | OpenAPIV3_1.ServerObject;

declare type ServerObject_2 = OpenAPIV3.ServerObject | OpenAPIV3_1.ServerObject;

/**
 * Apply plugins to a hooks instance.
 * Plugins are applied in order, and each can tap into hooks.
 */
export declare function UNSTABLE_applyPlugins(hooks: UNSTABLE_OazapftsPluginHooks, plugins: UNSTABLE_OazapftsPlugin[]): Promise<void>;

export declare type UNSTABLE_ComposeSourceHookArgs = [OazapftsContext, default_2.Statement[]];

declare type UNSTABLE_ComposeSourceHookArgs_2 = [OazapftsContext_2, default_2.Statement[]];

/**
 * Create a fresh Hooks instance for a generation run.
 */
export declare function UNSTABLE_createHooks(): {
    prepare: AsyncSeriesHook<[OazapftsContext], UnsetAdditionalOptions>;
    filterEndpoint: SyncWaterfallHook<[boolean, {
        method: HttpMethod_2;
        path: string;
        operation: OpenApi.OperationObject;
        pathItem: OpenApi.PathItemObject;
    }, OazapftsContext], boolean, UnsetAdditionalOptions>;
    generateMethod: AsyncSeriesBailHook<UNSTABLE_EndpointHookArgs, default_2.Statement[] | undefined, UnsetAdditionalOptions>;
    refineMethod: AsyncSeriesWaterfallHook<[default_2.Statement[], {
        method: HttpMethod_2;
        path: string;
        operation: OpenApi.OperationObject;
        pathItem: OpenApi.PathItemObject;
    }, OazapftsContext], default_2.Statement[], UnsetAdditionalOptions>;
    composeSource: AsyncSeriesBailHook<UNSTABLE_ComposeSourceHookArgs, default_2.Statement[] | undefined, UnsetAdditionalOptions>;
    refineSource: AsyncSeriesWaterfallHook<[default_2.Statement[], OazapftsContext, default_2.Statement[]], default_2.Statement[], UnsetAdditionalOptions>;
    querySerializerArgs: SyncWaterfallHook<UNSTABLE_QuerySerializerHookArgs, default_2.Expression[], UnsetAdditionalOptions>;
    astGenerated: AsyncSeriesWaterfallHook<[default_2.SourceFile, OazapftsContext], default_2.SourceFile, UnsetAdditionalOptions>;
};

/**
 * Create a oazapfts plugin
 */
export declare function UNSTABLE_createPlugin(fn: UNSTABLE_OazapftsPluginFn, options?: UNSTABLE_OazapftsPluginOptions): UNSTABLE_OazapftsPluginFn & UNSTABLE_OazapftsPluginOptions;

declare type UNSTABLE_DiscriminatingSchemaObject = Exclude<SchemaObject_2, boolean> & {
    discriminator: NonNullable<Exclude<SchemaObject_2, boolean>["discriminator"]>;
};

export declare type UNSTABLE_EndpointHookArgs = [
    {
    method: HttpMethod_2;
    path: string;
    operation: OpenApi.OperationObject;
    pathItem: OpenApi.PathItemObject;
},
OazapftsContext
];

declare type UNSTABLE_EndpointHookArgs_2 = [
    {
    method: HttpMethod;
    path: string;
    operation: OpenAPI.OperationObject;
    pathItem: OpenAPI.PathItemObject;
},
OazapftsContext_2
];

export declare enum UNSTABLE_OAZAPFTS_PLUGIN_PRECEDENCE {
    EAGER = "eager",
    DEFAULT = "default",
    LAZY = "lazy"
}

declare enum UNSTABLE_OAZAPFTS_PLUGIN_PRECEDENCE_2 {
    EAGER = "eager",
    DEFAULT = "default",
    LAZY = "lazy"
}

export declare type UNSTABLE_OazapftsPlugin = UNSTABLE_OazapftsPluginFn & UNSTABLE_OazapftsPluginOptions;

declare type UNSTABLE_OazapftsPlugin_2 = UNSTABLE_OazapftsPluginFn_2 & UNSTABLE_OazapftsPluginOptions_2;

/**
 * A plugin initiator function that receives hooks and can tap into them.
 */
export declare type UNSTABLE_OazapftsPluginFn = (hooks: UNSTABLE_OazapftsPluginHooks) => void | Promise<void>;

/**
 * A plugin initiator function that receives hooks and can tap into them.
 */
declare type UNSTABLE_OazapftsPluginFn_2 = (hooks: UNSTABLE_OazapftsPluginHooks_2) => void | Promise<void>;

export declare type UNSTABLE_OazapftsPluginHooks = {
    /**
     * Called after context is created with all template parts initialized.
     * Use this to modify the spec, context, or template parts.
     * This is the only hook where ctx.spec is mutable.
     */
    prepare: AsyncSeriesHook<[OazapftsContext]>;
    /**
     * Decide whether a given endpoint should be generated.
     * Receives the current decision (default true) as first argument.
     * Return false to skip endpoint generation.
     */
    filterEndpoint: SyncWaterfallHook<[
    boolean,
        {
        method: HttpMethod_2;
        path: string;
        operation: OpenApi.OperationObject;
        pathItem: OpenApi.PathItemObject;
    },
    OazapftsContext
    ]>;
    /**
     * Generate client methods for an endpoint.
     * This is a bail hook: the first plugin that returns a value wins.
     * Return `undefined` to delegate to later plugins.
     */
    generateMethod: AsyncSeriesBailHook<UNSTABLE_EndpointHookArgs, default_2.Statement[] | undefined>;
    /**
     * Refine client methods for an endpoint.
     * Receives generated methods and can return a modified array.
     * Runs after generateMethod for each endpoint.
     */
    refineMethod: AsyncSeriesWaterfallHook<[
    default_2.Statement[],
    ...UNSTABLE_EndpointHookArgs
    ]>;
    /**
     * Compose top-level source statements from context and generated methods.
     * This is a bail hook: the first plugin that returns a value wins.
     * Return `undefined` to delegate to later plugins.
     */
    composeSource: AsyncSeriesBailHook<UNSTABLE_ComposeSourceHookArgs, default_2.Statement[] | undefined>;
    /**
     * Refine top-level source statements before SourceFile construction.
     * Receives composed statements and can return a modified array.
     * Runs after composeSource.
     */
    refineSource: AsyncSeriesWaterfallHook<[
    default_2.Statement[],
    ...UNSTABLE_ComposeSourceHookArgs
    ]>;
    /**
     * Customize query serializer call arguments for each formatter call.
     * Default behavior is identity (returns the original args unchanged).
     */
    querySerializerArgs: SyncWaterfallHook<UNSTABLE_QuerySerializerHookArgs>;
    /**
     * Called after the full AST has been generated, before printing to string.
     * Use this to add/modify/remove statements from the final source file.
     */
    astGenerated: AsyncSeriesWaterfallHook<[default_2.SourceFile, OazapftsContext]>;
};

declare type UNSTABLE_OazapftsPluginHooks_2 = {
    /**
     * Called after context is created with all template parts initialized.
     * Use this to modify the spec, context, or template parts.
     * This is the only hook where ctx.spec is mutable.
     */
    prepare: AsyncSeriesHook<[OazapftsContext_2]>;
    /**
     * Decide whether a given endpoint should be generated.
     * Receives the current decision (default true) as first argument.
     * Return false to skip endpoint generation.
     */
    filterEndpoint: SyncWaterfallHook<[
    boolean,
        {
        method: HttpMethod;
        path: string;
        operation: OpenAPI.OperationObject;
        pathItem: OpenAPI.PathItemObject;
    },
    OazapftsContext_2
    ]>;
    /**
     * Generate client methods for an endpoint.
     * This is a bail hook: the first plugin that returns a value wins.
     * Return `undefined` to delegate to later plugins.
     */
    generateMethod: AsyncSeriesBailHook<UNSTABLE_EndpointHookArgs_2, default_2.Statement[] | undefined>;
    /**
     * Refine client methods for an endpoint.
     * Receives generated methods and can return a modified array.
     * Runs after generateMethod for each endpoint.
     */
    refineMethod: AsyncSeriesWaterfallHook<[
    default_2.Statement[],
    ...UNSTABLE_EndpointHookArgs_2
    ]>;
    /**
     * Compose top-level source statements from context and generated methods.
     * This is a bail hook: the first plugin that returns a value wins.
     * Return `undefined` to delegate to later plugins.
     */
    composeSource: AsyncSeriesBailHook<UNSTABLE_ComposeSourceHookArgs_2, default_2.Statement[] | undefined>;
    /**
     * Refine top-level source statements before SourceFile construction.
     * Receives composed statements and can return a modified array.
     * Runs after composeSource.
     */
    refineSource: AsyncSeriesWaterfallHook<[
    default_2.Statement[],
    ...UNSTABLE_ComposeSourceHookArgs_2
    ]>;
    /**
     * Customize query serializer call arguments for each formatter call.
     * Default behavior is identity (returns the original args unchanged).
     */
    querySerializerArgs: SyncWaterfallHook<UNSTABLE_QuerySerializerHookArgs_2>;
    /**
     * Called after the full AST has been generated, before printing to string.
     * Use this to add/modify/remove statements from the final source file.
     */
    astGenerated: AsyncSeriesWaterfallHook<[default_2.SourceFile, OazapftsContext_2]>;
};

export declare type UNSTABLE_OazapftsPluginOptions = {
    name?: string;
    version?: string;
    precedence?: UNSTABLE_OAZAPFTS_PLUGIN_PRECEDENCE;
};

declare type UNSTABLE_OazapftsPluginOptions_2 = {
    name?: string;
    version?: string;
    precedence?: UNSTABLE_OAZAPFTS_PLUGIN_PRECEDENCE_2;
};

export declare type UNSTABLE_QuerySerializerHookArgs = [
default_2.Expression[],
    {
    method: HttpMethod_2;
    path: string;
    operation: OpenApi.OperationObject;
    pathItem: OpenApi.PathItemObject;
    formatter: string;
    parameters: OpenApi.ParameterObject[];
    query: OpenApi.ParameterObject[];
},
OazapftsContext
];

declare type UNSTABLE_QuerySerializerHookArgs_2 = [
default_2.Expression[],
    {
    method: HttpMethod;
    path: string;
    operation: OpenAPI.OperationObject;
    pathItem: OpenAPI.PathItemObject;
    formatter: string;
    parameters: OpenAPI.ParameterObject[];
    query: OpenAPI.ParameterObject[];
},
OazapftsContext_2
];

export declare function UNSTABLE_sortPlugins<Plugin extends Pick<UNSTABLE_OazapftsPlugin, "precedence">>(plugins: Plugin[]): Plugin[];

export { }
