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';

declare type ArgumentStyle = (typeof argumentStyleOptions)[number];

declare const argumentStyleOptions: readonly ["positional", "object"];

export declare function createContext(inputSpec: Document_2, opts?: OazapftsContext["opts"]): OazapftsContext;

export declare type DefaultImport = [string, {
    from: string;
}];

declare type DefaultImport_2 = [string, {
    from: string;
}];

export 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 Document_2 = OpenAPIV3.Document | OpenAPIV3_1.Document;

declare type Document_2_2 = 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 const HttpMethods: readonly ["GET", "PUT", "POST", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"];

export declare type Import = string | ImportsWithoutDefault | DefaultImport | ImportWithDefault | NamespaceImport;

declare type Import_2 = string | ImportsWithoutDefault_2 | DefaultImport_2 | ImportWithDefault_2 | NamespaceImport_2;

export declare type ImportSpecifier = {
    name: string;
    as?: string;
};

declare type ImportSpecifier_2 = {
    name: string;
    as?: string;
};

export declare type ImportsWithoutDefault = [
(ImportSpecifier | string)[],
    {
    from: string;
}
];

declare type ImportsWithoutDefault_2 = [
(ImportSpecifier_2 | string)[],
    {
    from: string;
}
];

export declare type ImportWithDefault = [
string,
(ImportSpecifier | string)[],
    {
    from: string;
}
];

declare type ImportWithDefault_2 = [
string,
(ImportSpecifier_2 | string)[],
    {
    from: string;
}
];

export declare type NamespaceImport = [{
    namespace: string;
}, {
    from: string;
}];

declare type NamespaceImport_2 = [{
    namespace: string;
}, {
    from: string;
}];

export declare type OazapftsContext = {
    readonly opts: ReadonlyDeep<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_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>;
    typeAliases: Record<string, number>;
    operationNames: Map<string, number>;
};

declare type OazapftsContext_2 = {
    readonly opts: ReadonlyDeep_2<OazapftsOptions>;
    readonly spec: Document_2_2;
    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[];
    /** 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_2>;
    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[];
};

export declare type OnlyMode = "readOnly" | "writeOnly";

declare type OnlyMode_2 = "readOnly" | "writeOnly";

export 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
    }
}

export 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 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;

declare type UNSTABLE_ComposeSourceHookArgs = [OazapftsContext_2, default_2.Statement[]];

declare type UNSTABLE_EndpointHookArgs = [
    {
    method: HttpMethod;
    path: string;
    operation: OpenAPI.OperationObject;
    pathItem: OpenAPI.PathItemObject;
},
OazapftsContext_2
];

declare enum UNSTABLE_OAZAPFTS_PLUGIN_PRECEDENCE {
    EAGER = "eager",
    DEFAULT = "default",
    LAZY = "lazy"
}

declare type UNSTABLE_OazapftsPlugin = UNSTABLE_OazapftsPluginFn & UNSTABLE_OazapftsPluginOptions;

/**
 * A plugin initiator function that receives hooks and can tap into them.
 */
declare type UNSTABLE_OazapftsPluginFn = (hooks: UNSTABLE_OazapftsPluginHooks) => void | Promise<void>;

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_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, 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_2]>;
};

declare type UNSTABLE_OazapftsPluginOptions = {
    name?: string;
    version?: string;
    precedence?: UNSTABLE_OAZAPFTS_PLUGIN_PRECEDENCE;
};

declare type UNSTABLE_QuerySerializerHookArgs = [
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 withMode(ctx: OazapftsContext, mode?: OnlyMode): OazapftsContext;

export { }
