import { HookHandler, Plugin } from 'vite';
import * as zlib from 'zlib';
import { ZlibOptions, BrotliOptions } from 'zlib';

/**
 * A valid `picomatch` glob pattern, or array of patterns.
 */
type FilterPattern = ReadonlyArray<string | RegExp> | string | RegExp | null;

/**
 * Constructs a filter function which can be used to determine whether or not
 * certain modules should be operated upon.
 * @param include If `include` is omitted or has zero length, filter will return `true` by default.
 * @param exclude ID must not match any of the `exclude` patterns.
 * @param options Optionally resolves the patterns against a directory other than `process.cwd()`.
 * If a `string` is specified, then the value will be used as the base directory.
 * Relative paths will be resolved against `process.cwd()` first.
 * If `false`, then the patterns will not be resolved against any directory.
 * This can be useful if you want to create a filter for virtual module names.
 */
declare function createFilter(
  include?: FilterPattern,
  exclude?: FilterPattern,
  options?: { resolve?: string | false | null }
): (id: string | unknown) => boolean;

interface NodeDescriptor<T = Record<string, NonNullable<unknown>>> {
    meta: T;
    filename: string;
}
interface GroupWithNode {
    groups: Array<GroupWithNode>;
    children?: Map<string, Node>;
    filename: string;
    label: string;
    [prop: string]: any;
}
declare class Node<T = NonNullable<unknown>> implements NodeDescriptor<T> {
    meta: T;
    filename: string;
    children: Map<string, Node<T>>;
    groups: Array<GroupWithNode>;
    isEndOfPath: boolean;
    constructor(options?: Partial<NodeDescriptor<T>>);
}

interface AnalyzerModuleOptions {
    gzip?: ZlibOptions;
    brotli?: BrotliOptions;
    include?: FilterPattern;
    exclude?: FilterPattern;
    pathFormatter?: (path: string, defaultWD: string) => string;
}
interface SerializedModWithAsset {
    code: string;
    filename: string;
    kind: 'asset';
}
interface SerializedModWithChunk {
    code: string;
    filename: string;
    map: string;
    imports: string[];
    dynamicImports: string[];
    moduleIds: string[];
    isEntry: boolean;
    kind: 'chunk';
}
type SerializedMod = SerializedModWithAsset | SerializedModWithChunk;
declare function createCompressAlorithm(opt: AnalyzerModuleOptions): {
    gzip: (buf: zlib.InputType) => Promise<Buffer<ArrayBufferLike>>;
    brotli: (buf: zlib.InputType) => Promise<Buffer<ArrayBufferLike>>;
};
declare class AnalyzerNode {
    originalId: string;
    filename: string;
    label: string;
    parsedSize: number;
    mapSize: number;
    gzipSize: number;
    brotliSize: number;
    source: Array<GroupWithNode>;
    imports: Set<string>;
    isAsset: boolean;
    isEntry: boolean;
    constructor(originalId: string);
    private addImports;
    setup(mod: SerializedMod, compress: ReturnType<typeof createCompressAlorithm>, workspaceRoot: string, matcher: ReturnType<typeof createFilter>, pathFormatter: PathFormatter): Promise<void>;
}
declare class AnalyzerModule {
    compressAlorithm: ReturnType<typeof createCompressAlorithm>;
    modules: AnalyzerNode[];
    workspaceRoot: string;
    pluginContext: PluginContext | null;
    private chunks;
    private matcher;
    private pathFormatter;
    constructor(opt?: AnalyzerModuleOptions);
    installPluginContext(context: PluginContext): void;
    setupRollupChunks(chunks: OutputBundle, watchMode?: boolean): void;
    addModule(mod: OutputChunk | OutputAsset): Promise<void>;
    processModule(): Module[];
}

type RenderChunkFunction = NonNullable<HookHandler<Plugin['renderChunk']>>;
type GenerateBundleFunction = NonNullable<HookHandler<Plugin['generateBundle']>>;
type PluginContext = ThisParameterType<RenderChunkFunction>;
type OutputBundle = Parameters<GenerateBundleFunction>[1];
type OutputAsset = Extract<OutputBundle[0], {
    type: 'asset';
}>;
type OutputChunk = Extract<OutputBundle[0], {
    type: 'chunk';
}>;
type AnalyzerMode = 'static' | 'json' | 'server';
type DefaultSizes = 'stat' | 'gzip' | 'brotli';
interface Module {
    label: string;
    filename: string;
    isEntry: boolean;
    parsedSize: number;
    mapSize: number;
    gzipSize: number;
    brotliSize: number;
    source: Array<Module>;
    stats: Array<Module>;
    imports: Array<string>;
    groups: Array<Module>;
    isAsset?: boolean;
}
type CustomAnalyzerModule = (analyzeModule: Module[]) => void;
type PathFormatter = (path: string, defaultWD: string) => string;
interface BasicAnalyzerPluginOptions {
    enabled?: boolean;
    summary?: boolean;
    include?: FilterPattern;
    exclude?: FilterPattern;
    analyzerMode?: AnalyzerMode | CustomAnalyzerModule;
    reportTitle?: string;
    defaultSizes?: DefaultSizes;
    gzipOptions?: ZlibOptions;
    brotliOptions?: BrotliOptions;
    pathFormatter?: PathFormatter;
}
interface AnalyzerPluginOptionsWithServer extends BasicAnalyzerPluginOptions {
    analyzerMode?: 'server';
    analyzerPort?: number | 'auto';
    openAnalyzer?: boolean;
}
type FileNameDesc = (outputDir: string) => string;
interface AnalyzerPluginOptionsWithJson extends BasicAnalyzerPluginOptions {
    analyzerMode?: 'json';
    fileName?: string | FileNameDesc;
}
interface AnalyzerPluginOptionsWithStatic extends BasicAnalyzerPluginOptions {
    analyzerMode?: 'static';
    analyzerPort?: number | 'auto';
    openAnalyzer?: boolean;
    fileName?: string | FileNameDesc;
}
interface AnalyzerPluginOptionsWithCustom extends BasicAnalyzerPluginOptions {
    analyzerMode: CustomAnalyzerModule;
}
type AnalyzerPluginOptions = AnalyzerPluginOptionsWithServer | AnalyzerPluginOptionsWithStatic | AnalyzerPluginOptionsWithJson | AnalyzerPluginOptionsWithCustom;
interface AnalyzerStore {
    analyzerModule: AnalyzerModule;
    lastSourcemapOption: boolean;
    hasSetupSourcemapOption: boolean;
    pluginOptions: AnalyzerPluginOptions;
    preferLivingServer: boolean;
    preferSilent: boolean;
}
interface AnalyzerPluginInternalAPI {
    store: AnalyzerStore;
    processModule(): Module[];
}

export type { AnalyzerPluginInternalAPI as A, DefaultSizes as D, Module as M, AnalyzerPluginOptions as a, AnalyzerMode as b };
