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 { SourceFile } from 'typescript';
import { Statement } from 'typescript';
import { SyncWaterfallHook } from 'tapable';
import { TypeAliasDeclaration } from 'typescript';
import { TypeReferenceNode } from 'typescript';

declare function addComment<T extends default_2.Node>(node: T, comment?: string): T;

declare function appendNodes<T extends default_2.Node>(array: default_2.NodeArray<T>, ...nodes: T[]): default_2.NodeArray<T>;

declare type ArgumentStyle = (typeof argumentStyleOptions)[number];

declare const argumentStyleOptions: readonly ["positional", "object"];

declare function block(...statements: default_2.Statement[]): default_2.Block;

declare function changePropertyValue(o: default_2.ObjectLiteralExpression, property: string, value: default_2.Expression): void;

declare function createArrowFunction(parameters: default_2.ParameterDeclaration[], body: default_2.ConciseBody, { modifiers, typeParameters, type, equalsGreaterThanToken, }?: {
    modifiers?: default_2.Modifier[];
    typeParameters?: default_2.TypeParameterDeclaration[];
    type?: default_2.TypeNode;
    equalsGreaterThanToken?: default_2.EqualsGreaterThanToken;
}): default_2.ArrowFunction;

declare function createCall(expression: default_2.Expression | string, { typeArgs, args, }?: {
    typeArgs?: Array<default_2.TypeNode>;
    args?: Array<default_2.Expression>;
}): default_2.CallExpression;

declare function createClassDeclaration({ modifiers, name, typeParameters, heritageClauses, members, }: {
    modifiers?: Array<default_2.Modifier>;
    name?: string | default_2.Identifier;
    typeParameters?: Array<default_2.TypeParameterDeclaration>;
    heritageClauses?: Array<default_2.HeritageClause>;
    members: Array<default_2.ClassElement>;
}): default_2.ClassDeclaration;

declare function createConstructor({ modifiers, parameters, body, }: {
    modifiers?: Array<default_2.Modifier>;
    parameters: Array<default_2.ParameterDeclaration>;
    body?: default_2.Block;
}): default_2.ConstructorDeclaration;

declare function createEnumTypeNode(values: Array<string | boolean | number>): default_2.LiteralTypeNode | default_2.UnionTypeNode;

declare function createFunctionDeclaration(name: string | default_2.Identifier | undefined, { modifiers, asteriskToken, typeParameters, type, }: {
    modifiers?: default_2.Modifier[];
    asteriskToken?: default_2.AsteriskToken;
    typeParameters?: default_2.TypeParameterDeclaration[];
    type?: default_2.TypeNode;
}, parameters: default_2.ParameterDeclaration[], body?: default_2.Block): default_2.FunctionDeclaration;

declare function createIndexSignature(type: default_2.TypeNode, { modifiers, indexName, indexType, }?: {
    indexName?: string;
    indexType?: default_2.TypeNode;
    modifiers?: Array<default_2.Modifier>;
}): default_2.IndexSignatureDeclaration;

declare function createInterfaceAliasDeclaration({ modifiers, name, typeParameters, type, inheritedNodeNames, }: {
    modifiers?: Array<default_2.Modifier>;
    name: string | default_2.Identifier;
    typeParameters?: Array<default_2.TypeParameterDeclaration>;
    type: default_2.TypeNode;
    inheritedNodeNames?: (string | default_2.Identifier)[];
}): default_2.InterfaceDeclaration;

declare function createKeywordType(type: KeywordTypeName): default_2.KeywordTypeNode<default_2.SyntaxKind.AnyKeyword> | default_2.KeywordTypeNode<default_2.SyntaxKind.NumberKeyword> | default_2.KeywordTypeNode<default_2.SyntaxKind.ObjectKeyword> | default_2.KeywordTypeNode<default_2.SyntaxKind.StringKeyword> | default_2.KeywordTypeNode<default_2.SyntaxKind.BooleanKeyword> | default_2.KeywordTypeNode<default_2.SyntaxKind.UndefinedKeyword> | default_2.KeywordTypeNode<default_2.SyntaxKind.VoidKeyword> | default_2.KeywordTypeNode<default_2.SyntaxKind.NeverKeyword> | default_2.LiteralTypeNode | default_2.KeywordTypeNode<default_2.SyntaxKind.UnknownKeyword>;

declare function createLiteral(v: string | boolean | number): default_2.StringLiteral | default_2.TrueLiteral | default_2.FalseLiteral | default_2.NumericLiteral | default_2.PrefixUnaryExpression;

declare function createMethod(name: string | default_2.Identifier | default_2.StringLiteral | default_2.NumericLiteral | default_2.ComputedPropertyName, { modifiers, asteriskToken, questionToken, typeParameters, type, }?: {
    modifiers?: default_2.Modifier[];
    asteriskToken?: default_2.AsteriskToken;
    questionToken?: default_2.QuestionToken | boolean;
    typeParameters?: default_2.TypeParameterDeclaration[];
    type?: default_2.TypeNode;
}, parameters?: default_2.ParameterDeclaration[], body?: default_2.Block): default_2.MethodDeclaration;

declare function createMethodCall(method: string, opts: {
    typeArgs?: Array<default_2.TypeNode>;
    args?: Array<default_2.Expression>;
}): default_2.CallExpression;

declare function createObjectBinding(elements: Array<{
    name: string | default_2.BindingName;
    dotDotDotToken?: default_2.DotDotDotToken;
    propertyName?: string | default_2.PropertyName;
    initializer?: default_2.Expression;
}>): default_2.ObjectBindingPattern;

declare function createObjectLiteral(props: [string, string | default_2.Expression][]): default_2.ObjectLiteralExpression;

declare function createParameter(name: string | default_2.BindingName, { modifiers, dotDotDotToken, questionToken, type, initializer, }: {
    modifiers?: Array<default_2.Modifier>;
    dotDotDotToken?: default_2.DotDotDotToken;
    questionToken?: default_2.QuestionToken | boolean;
    type?: default_2.TypeNode;
    initializer?: default_2.Expression;
}): default_2.ParameterDeclaration;

declare function createPropertyAssignment(name: string, expression: default_2.Expression): default_2.PropertyAssignment | default_2.ShorthandPropertyAssignment;

declare function createPropertySignature({ modifiers, name, questionToken, type, }: {
    modifiers?: Array<default_2.Modifier>;
    name: default_2.PropertyName | string;
    questionToken?: default_2.QuestionToken | boolean;
    type?: default_2.TypeNode;
}): default_2.PropertySignature;

declare function createQuestionToken(token?: boolean | default_2.QuestionToken): default_2.QuestionToken | undefined;

declare function createTemplateString(head: string, spans: Array<{
    literal: string;
    expression: default_2.Expression;
}>): default_2.StringLiteral | default_2.TemplateExpression;

declare function createTypeAliasDeclaration({ modifiers, name, typeParameters, type, }: {
    modifiers?: Array<default_2.Modifier>;
    name: string | default_2.Identifier;
    typeParameters?: Array<default_2.TypeParameterDeclaration>;
    type: default_2.TypeNode;
}): default_2.TypeAliasDeclaration;

declare type DefaultImport = [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 DiscriminatorObject = OpenAPIV3.DiscriminatorObject | OpenAPIV3_1.DiscriminatorObject;

declare type Document_2 = OpenAPIV3.Document | OpenAPIV3_1.Document;

declare type EnumStyle = (typeof enumStyleOptions)[number];

declare const enumStyleOptions: readonly ["union", "enum", "as-const"];

declare function findFirstVariableDeclaration(nodes: default_2.NodeArray<default_2.Node>, name: string): default_2.VariableDeclaration;

declare function findNode<T extends default_2.Node>(nodes: default_2.NodeArray<default_2.Node>, kind: T extends {
    kind: infer K;
} ? K : never, test?: (node: T) => boolean | undefined): T;

/**
 * Create an Typescript AST from an OpenAPI document.
 *
 * @param ctx - Oazapfts context
 * @param UNSTABLE_plugins - Unstable plugins to apply
 * @returns The generated TypeScript AST
 */
export declare function generateAst(ctx: OazapftsContext, UNSTABLE_plugins?: UNSTABLE_OazapftsPlugin[]): Promise<SourceFile>;

/**
 * Create a a TypeScript source file from an OpenAPI spec.
 *
 * @param spec - Path to an OpenAPI spec file or source string
 * @param opts - Options for the code generation
 * @returns The generated TypeScript source file
 */
declare function generateSource(spec: string, opts?: OazapftsOptions): Promise<string>;
export default generateSource;
export { generateSource }
export { generateSource as oazapfts }

declare function getFirstDeclarationName(n: default_2.VariableStatement): string | (void & {
    __escapedIdentifier: void;
});

declare function getName(name: default_2.Node): string | (void & {
    __escapedIdentifier: void;
});

declare type HttpMethod = (typeof HttpMethods)[number];

declare const HttpMethods: readonly ["GET", "PUT", "POST", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"];

declare type Import = string | ImportsWithoutDefault | DefaultImport | ImportWithDefault | NamespaceImport;

declare type ImportSpecifier = {
    name: string;
    as?: string;
};

declare type ImportsWithoutDefault = [
(ImportSpecifier | string)[],
    {
    from: string;
}
];

declare type ImportWithDefault = [
string,
(ImportSpecifier | string)[],
    {
    from: string;
}
];

declare function isValidIdentifier(str: string): boolean;

declare const keywordType: {
    any: default_2.KeywordTypeNode<default_2.SyntaxKind.AnyKeyword>;
    number: default_2.KeywordTypeNode<default_2.SyntaxKind.NumberKeyword>;
    integer: default_2.KeywordTypeNode<default_2.SyntaxKind.NumberKeyword>;
    object: default_2.KeywordTypeNode<default_2.SyntaxKind.ObjectKeyword>;
    string: default_2.KeywordTypeNode<default_2.SyntaxKind.StringKeyword>;
    boolean: default_2.KeywordTypeNode<default_2.SyntaxKind.BooleanKeyword>;
    undefined: default_2.KeywordTypeNode<default_2.SyntaxKind.UndefinedKeyword>;
    void: default_2.KeywordTypeNode<default_2.SyntaxKind.VoidKeyword>;
    never: default_2.KeywordTypeNode<default_2.SyntaxKind.NeverKeyword>;
    null: default_2.LiteralTypeNode;
    unknown: default_2.KeywordTypeNode<default_2.SyntaxKind.UnknownKeyword>;
};

declare type KeywordTypeName = keyof typeof keywordType;

declare type MediaTypeObject = OpenAPIV3.MediaTypeObject | OpenAPIV3_1.MediaTypeObject;

declare const modifier: {
    async: default_2.ModifierToken<default_2.SyntaxKind.AsyncKeyword>;
    export: default_2.ModifierToken<default_2.SyntaxKind.ExportKeyword>;
};

declare type NamespaceImport = [{
    namespace: string;
}, {
    from: string;
}];

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[];
    /** 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>;
};

export 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[];
};

declare type OnlyMode = "readOnly" | "writeOnly";

declare type OnlyModes = Record<OnlyMode, boolean>;

declare namespace OpenAPI {
    export {
        SchemaObject,
        UNSTABLE_DiscriminatingSchemaObject,
        ReferenceObject,
        ParameterObject,
        Document_2 as Document,
        DiscriminatorObject,
        ResponseObject,
        ResponsesObject,
        RequestBodyObject,
        MediaTypeObject,
        OperationObject,
        PathsObject,
        PathItemObject,
        ServerObject
    }
}
export { OpenAPI }

declare type OperationObject = OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject;

declare type ParameterObject = OpenAPIV3.ParameterObject | OpenAPIV3_1.ParameterObject;

/**
 * Parse an OpenAPI spec into a document object.
 *
 * @param spec - Path to a local OpenAPI spec file,
 *                or a URL to an OpenAPI spec file
 *                or a OpenAPI document object
 * @returns The parsed OpenAPI document
 */
export declare function parseSpec(spec: string | OpenAPI.Document): Promise<OpenAPIV3<    {}> | OpenAPIV3_1<    {}>>;

declare type PathItemObject = OpenAPIV3.PathItemObject | OpenAPIV3_1.PathItemObject;

declare type PathsObject = OpenAPIV3.PathsObject | OpenAPIV3_1.PathsObject;

/**
 * Print a TypeScript AST to a string.
 *
 * @param ast - The TypeScript AST to print
 * @returns The printed TypeScript source
 */
export declare function printAst(ast: SourceFile): string;

declare function printFile(sourceFile: default_2.SourceFile): string;

declare function printNode(node: default_2.Node): string;

declare function printNodes(nodes: default_2.Node[]): string;

declare const questionToken: default_2.PunctuationToken<default_2.SyntaxKind.QuestionToken>;

declare type ReadonlyDeep<T> = {
    readonly [P in keyof T]: ReadonlyDeep<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 ServerObject = OpenAPIV3.ServerObject | OpenAPIV3_1.ServerObject;

declare function toExpression(ex: default_2.Expression | string): default_2.Expression;

declare function transform<T extends default_2.Node>(source: T, ...visitors: Visitor[]): T;

declare namespace UNSTABLE_cg {
    export {
        createQuestionToken,
        createKeywordType,
        createLiteral,
        createEnumTypeNode,
        createTypeAliasDeclaration,
        createInterfaceAliasDeclaration,
        toExpression,
        createCall,
        createMethodCall,
        createObjectLiteral,
        createPropertyAssignment,
        block,
        createArrowFunction,
        createFunctionDeclaration,
        createClassDeclaration,
        createConstructor,
        createMethod,
        createParameter,
        createPropertySignature,
        createIndexSignature,
        createObjectBinding,
        createTemplateString,
        findNode,
        getName,
        getFirstDeclarationName,
        findFirstVariableDeclaration,
        changePropertyValue,
        transform,
        appendNodes,
        addComment,
        printNode,
        printNodes,
        printFile,
        isValidIdentifier,
        updateVariableDeclaration,
        updateFunctionDeclaration,
        questionToken,
        keywordType,
        modifier
    }
}
export { UNSTABLE_cg }

declare type UNSTABLE_ComposeSourceHookArgs = [OazapftsContext, default_2.Statement[]];

declare type UNSTABLE_DiscriminatingSchemaObject = Exclude<SchemaObject, boolean> & {
    discriminator: NonNullable<Exclude<SchemaObject, boolean>["discriminator"]>;
};

declare type UNSTABLE_EndpointHookArgs = [
    {
    method: HttpMethod;
    path: string;
    operation: OpenAPI.OperationObject;
    pathItem: OpenAPI.PathItemObject;
},
OazapftsContext
];

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]>;
    /**
     * 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
    ]>;
    /**
     * 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_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
];

declare function updateFunctionDeclaration(node: default_2.FunctionDeclaration, updates: Partial<default_2.FunctionDeclaration>): default_2.FunctionDeclaration;

declare function updateVariableDeclaration(node: default_2.VariableDeclaration, updates: Partial<default_2.VariableDeclaration>): default_2.VariableDeclaration;

declare type Visitor = (node: default_2.Node, context: default_2.TransformationContext) => void | default_2.Node;

export { }
