import type { FlowrSearchElement, FlowrSearchElements, FlowrSearchInput } from '../flowr-search';
import type { ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
import type { Pipeline } from '../../core/steps/pipeline/pipeline';
import type { MergeableRecord } from '../../util/objects';
import type { Identifier } from '../../dataflow/environments/identifier';
import type { LinkToLastCall } from '../../queries/catalog/call-context-query/call-context-query-format';
import { type NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
import type { ControlFlowInformation } from '../../control-flow/control-flow-graph';
import type { QueryResult, SynchronousQuery } from '../../queries/query';
import type { CfgSimplificationPassName } from '../../control-flow/cfg-simplification';
import type { AsyncOrSyncType } from 'ts-essentials';
export interface EnrichmentData<ElementContent extends MergeableRecord, ElementArguments = undefined, SearchContent extends MergeableRecord = never, SearchArguments = ElementArguments> {
    /**
     * A function that is applied to each element of the search to enrich it with additional data.
     */
    readonly enrichElement?: (element: FlowrSearchElement<ParentInformation>, search: FlowrSearchElements<ParentInformation>, data: FlowrSearchInput<Pipeline>, args: ElementArguments | undefined, previousValue: ElementContent | undefined) => ElementContent;
    readonly enrichSearch?: (search: FlowrSearchElements<ParentInformation>, data: FlowrSearchInput<Pipeline>, args: SearchArguments | undefined, previousValue: SearchContent | undefined) => SearchContent;
    /**
     * The mapping function used by the {@link Mapper.Enrichment} mapper.
     */
    readonly mapper?: (content: ElementContent) => FlowrSearchElement<ParentInformation>[];
}
export type EnrichmentElementContent<E extends Enrichment> = typeof Enrichments[E] extends EnrichmentData<infer EC, infer _EA, infer _SC, infer _SA> ? EC : never;
export type EnrichmentElementArguments<E extends Enrichment> = typeof Enrichments[E] extends EnrichmentData<infer _EC, infer EA, infer _SC, infer _SA> ? EA : never;
export type EnrichmentSearchContent<E extends Enrichment> = typeof Enrichments[E] extends EnrichmentData<infer _EC, infer _EA, infer SC, infer _SA> ? SC : never;
export type EnrichmentSearchArguments<E extends Enrichment> = typeof Enrichments[E] extends EnrichmentData<infer _EC, infer _EA, infer _SC, infer SA> ? SA : never;
/**
 * An enumeration that stores the names of the available enrichments that can be applied to a set of search elements.
 * See {@link FlowrSearchBuilder.with} for more information on how to apply enrichments.
 */
export declare enum Enrichment {
    CallTargets = "call-targets",
    LastCall = "last-call",
    CfgInformation = "cfg-information",
    QueryData = "query-data"
}
export interface CallTargetsContent extends MergeableRecord {
    /**
     * The call targets of the function call.
     * For identifier call targets, the identifier is the name of the library function being called.
     */
    targets: (FlowrSearchElement<ParentInformation> | Identifier)[];
}
export interface LastCallContent extends MergeableRecord {
    linkedIds: FlowrSearchElement<ParentInformation>[];
}
export interface CfgInformationElementContent extends MergeableRecord {
    /**
     * Whether the current node is a root node in the CFG, which is a node that is not contained inside of a function definition.
     */
    isRoot: boolean;
    /**
     * Whether the current node is reachable from the root of the CFG.
     * Only has a value if {@link CfgInformationArguments.checkReachable} was true.
     */
    isReachable?: boolean;
}
export interface CfgInformationSearchContent extends MergeableRecord {
    /**
     * The CFG attached to the search, extracted using {@link extractCfg}.
     */
    cfg: ControlFlowInformation;
    /**
     * The set of all nodes that are reachable from the root of the CFG, extracted using {@link visitCfgInOrder}.
     * Only has a value if {@link CfgInformationArguments.checkReachable} was true.
     */
    reachableNodes?: Set<NodeId>;
}
export interface CfgInformationArguments extends MergeableRecord {
    /** Whether to recalculate the CFG information if it already exists on the current search. Defaults to `false`. */
    forceRefresh?: boolean;
    /** The simplification passes that should be run on the extracted CFG. Defaults to the entries of {@link DefaultCfgSimplificationOrder}. */
    simplificationPasses?: CfgSimplificationPassName[];
    /** Whether to check nodes for reachability, and subsequently set {@link CfgInformationSearchContent.reachableNodes} and {@link CfgInformationElementContent.isReachable}. Defaults to `false`. */
    checkReachable?: boolean;
}
export interface QueryDataElementContent extends MergeableRecord {
    /** The name of the query that this element originated from. To get each query's data, see {@link QueryDataSearchContent}. */
    query: SynchronousQuery['type'];
}
export interface QueryDataSearchContent extends MergeableRecord {
    queries: {
        [QueryType in SynchronousQuery['type']]: AsyncOrSyncType<QueryResult<QueryType>>;
    };
}
/**
 * The registry of enrichments that are currently supported by the search.
 * See {@link FlowrSearchBuilder.with} for more information on how to apply enrichments.
 */
export declare const Enrichments: {
    readonly "call-targets": {
        enrichElement: (e: FlowrSearchElement<ParentInformation>, _s: FlowrSearchElements<ParentInformation, FlowrSearchElement<ParentInformation>[]>, data: import("../../core/steps/pipeline/pipeline").PipelineOutput<Pipeline<import("../../core/steps/pipeline-step").IPipelineStep<import("../../core/steps/pipeline-step").PipelineStepName, (...args: any[]) => any>>> & {
            normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
            dataflow: import("../../dataflow/info").DataflowInformation;
            config: import("../../config").FlowrConfigOptions;
        }, args: {
            onlyBuiltin?: boolean;
        } | undefined, prev: CallTargetsContent | undefined) => CallTargetsContent;
        mapper: ({ targets }: CallTargetsContent) => FlowrSearchElement<ParentInformation>[];
    };
    readonly "last-call": {
        enrichElement: (e: FlowrSearchElement<ParentInformation>, _s: FlowrSearchElements<ParentInformation, FlowrSearchElement<ParentInformation>[]>, data: import("../../core/steps/pipeline/pipeline").PipelineOutput<Pipeline<import("../../core/steps/pipeline-step").IPipelineStep<import("../../core/steps/pipeline-step").PipelineStepName, (...args: any[]) => any>>> & {
            normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
            dataflow: import("../../dataflow/info").DataflowInformation;
            config: import("../../config").FlowrConfigOptions;
        }, args: Omit<LinkToLastCall<string | RegExp>, "type">[] | undefined, prev: LastCallContent | undefined) => LastCallContent;
        mapper: ({ linkedIds }: LastCallContent) => FlowrSearchElement<ParentInformation>[];
    };
    readonly "cfg-information": {
        enrichElement: (e: FlowrSearchElement<ParentInformation>, search: FlowrSearchElements<ParentInformation, FlowrSearchElement<ParentInformation>[]>, _data: import("../../core/steps/pipeline/pipeline").PipelineOutput<Pipeline<import("../../core/steps/pipeline-step").IPipelineStep<import("../../core/steps/pipeline-step").PipelineStepName, (...args: any[]) => any>>> & {
            normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
            dataflow: import("../../dataflow/info").DataflowInformation;
            config: import("../../config").FlowrConfigOptions;
        }, _args: CfgInformationArguments | undefined, prev: CfgInformationElementContent | undefined) => {
            isRoot: boolean;
            isReachable: boolean | undefined;
        };
        enrichSearch: (_search: FlowrSearchElements<ParentInformation, FlowrSearchElement<ParentInformation>[]>, data: import("../../core/steps/pipeline/pipeline").PipelineOutput<Pipeline<import("../../core/steps/pipeline-step").IPipelineStep<import("../../core/steps/pipeline-step").PipelineStepName, (...args: any[]) => any>>> & {
            normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
            dataflow: import("../../dataflow/info").DataflowInformation;
            config: import("../../config").FlowrConfigOptions;
        }, args: CfgInformationArguments | undefined, prev: CfgInformationSearchContent | undefined) => CfgInformationSearchContent;
    };
    readonly "query-data": {
        enrichElement: (_e: FlowrSearchElement<ParentInformation>, _search: FlowrSearchElements<ParentInformation, FlowrSearchElement<ParentInformation>[]>, _data: import("../../core/steps/pipeline/pipeline").PipelineOutput<Pipeline<import("../../core/steps/pipeline-step").IPipelineStep<import("../../core/steps/pipeline-step").PipelineStepName, (...args: any[]) => any>>> & {
            normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
            dataflow: import("../../dataflow/info").DataflowInformation;
            config: import("../../config").FlowrConfigOptions;
        }, args: QueryDataElementContent | undefined, prev: QueryDataElementContent | undefined) => QueryDataElementContent;
        enrichSearch: (_search: FlowrSearchElements<ParentInformation, FlowrSearchElement<ParentInformation>[]>, _data: import("../../core/steps/pipeline/pipeline").PipelineOutput<Pipeline<import("../../core/steps/pipeline-step").IPipelineStep<import("../../core/steps/pipeline-step").PipelineStepName, (...args: any[]) => any>>> & {
            normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
            dataflow: import("../../dataflow/info").DataflowInformation;
            config: import("../../config").FlowrConfigOptions;
        }, args: QueryDataSearchContent | undefined, prev: QueryDataSearchContent | undefined) => Required<QueryDataSearchContent>;
    };
};
/**
 * Returns the content of the given enrichment type from a {@link FlowrSearchElement}.
 * If the search element is not enriched with the given enrichment, `undefined` is returned.
 * @param e - The search element whose enrichment content should be retrieved.
 * @param enrichment - The enrichment content, if present, else `undefined`.
 */
export declare function enrichmentContent<E extends Enrichment>(e: FlowrSearchElement<ParentInformation>, enrichment: E): EnrichmentElementContent<E>;
export declare function enrichElement<Element extends FlowrSearchElement<ParentInformation>, E extends Enrichment>(e: Element, s: FlowrSearchElements<ParentInformation>, data: FlowrSearchInput<Pipeline>, enrichment: E, args?: EnrichmentElementArguments<E>): Element;
