import type { Plugin } from '@servicenow/sdk-build-core';
import type { Project } from '../../project';
type Via = {
    type: 'string';
    value: string;
} | {
    type: 'object';
    value: Record<string, string>;
} | {
    type: 'regex';
    value: {
        parent: [string, string];
        child: [string, string];
    }[];
} | {
    type: 'unknown';
    value: unknown;
};
/**
 * Represents a descendant relationship in the hierarchy tree with metadata.
 * Includes node identification, relationship type, and potential cyclic references.
 */
type DescendantRelationship = {
    nodeId: string;
    table: string;
    via: Via;
    inverse: boolean;
    composite: boolean;
    cycleTargetNodeId?: string;
    cyclicReferences?: string[];
    relationships?: DescendantRelationships;
};
/**
 * A map of descendant table names to their relationship metadata.
 */
type DescendantRelationships = {
    [descendantTable: string]: DescendantRelationship;
};
/**
 * Represents the complete relationship hierarchy for a given table.
 * @template T - The table name type
 */
export type RelationshipHierarchy<T extends string> = Record<T, {
    nodeId: string;
    table: T;
    composite: boolean;
    cyclicReferences?: string[];
    relationships?: DescendantRelationships;
}>;
/**
 * Collects every table name in a relationship hierarchy (the root plus all
 * descendants, recursively).
 */
export declare function collectTablesFromHierarchy(hierarchy: RelationshipHierarchy<string>): Set<string>;
/**
 * Returns root tables for a plugin — tables from getTables() that are not
 * marked as descendants in any relationship.
 */
export declare function getRootTables(plugin: Plugin): Set<string>;
/**
 * Resolves and manages table relationships spread across plugins.
 * Builds hierarchical relationship trees, detects cycles, and identifies root tables.
 */
export declare class RelationshipResolver {
    private readonly project;
    private readonly descendantParents;
    private readonly parentDescendantRelations;
    private readonly pluginRoots;
    private nodeIdCounter;
    /**
     * Creates a new RelationshipResolver instance.
     * @param project - The project containing the table relationships to resolve
     */
    constructor(project: Project);
    /**
     * Generates a unique node identifier for the relationship tree.
     * @returns A unique node ID string
     */
    private generateNodeId;
    /**
     * Initializes the resolver by processing all relationships from project plugins.
     * Populates internal maps tracking parent-descendant relationships.
     * Also identifies plugin entry-point tables: tables with toShape that are not
     * descendants within that same plugin. These are treated as roots even if
     * another plugin claims them as descendants.
     */
    private init;
    /**
     * Normalizes the 'via' field of a relationship into a consistent format.
     * @param via - The relationship via field (string, object, or regex)
     * @returns A normalized Via object with type and value
     */
    private normalizeVia;
    private isComposite;
    /**
     * Recursively processes relationships for a parent table.
     * Updates internal maps tracking descendant-parent relationships.
     * @param parent - The parent table name
     * @param relationships - The relationships configuration for the parent table
     */
    private processRelationship;
    /**
     * Finds all root tables (tables with no parents) for a given table.
     * Uses depth-first search with cycle detection.
     * A table is considered a root if it has no parents in the merged graph,
     * or if it is an entry-point table declared by any plugin (appears in a
     * plugin's relationship graph but not as a descendant within that plugin).
     * @param table - The table to find roots for
     * @param visited - Set of already visited tables to prevent infinite loops
     * @returns Set of root table names
     */
    private findAllRoots;
    /**
     * Adds cyclic reference metadata to the relationship tree.
     * @param relationships - The relationship tree to annotate
     * @param cyclicRefs - Map of node IDs to their cyclic reference node IDs
     */
    private addCyclicReferencesToTree;
    /**
     * Recursively builds the relationship tree for a table.
     * Detects and marks cyclic relationships during traversal.
     * @param table - The table to build relationships for
     * @param visitedPath - Map of visited tables to their node IDs in current path
     * @param cyclicRefs - Map collecting cyclic references by node ID
     * @returns The descendant relationships tree, or undefined if no relationships exist
     */
    private buildRelationship;
    /**
     * Generates the complete relationship hierarchy for a given table.
     * @template T - The table name type
     * @param table - The root table to generate hierarchy for
     * @returns The complete relationship hierarchy including cyclic references
     */
    generateRelationshipHierarchy<T extends string>(table: T): RelationshipHierarchy<T>;
    /**
     * Checks if a table is a root table (has no parent tables).
     * Assumption: Root table doesn't have any parent table even via cylic references.
     * @param table - The table name to check
     * @returns True if the table is a root, false otherwise
     */
    private isRoot;
    /**
     * Validates that all 'via' fields in the hierarchy are supported types.
     * Currently rejects hierarchies containing unknown type relationships.
     * @param hierarchy - The relationship hierarchy to validate
     * @returns True if all via fields are supported, false otherwise
     */
    private validateViaInHierarchy;
    /**
     * Resolves all possible relationship hierarchies for a given table.
     * Finds all root tables and generates hierarchies from each root.
     * Filters out hierarchies with unsupported relationship types.
     * @param table - The table to resolve relationships for
     * @returns Array of all valid relationship hierarchies
     */
    resolveRelationship(table: string): RelationshipHierarchy<string>[];
    /**
     * Gets the plugin root tables for a given table by traversing upward.
     * Useful for warning users when they pass a non-root table.
     * @param table - The table to find plugin roots for
     * @returns Set of plugin root table names, empty if the table has no parents
     *          in the merged relationship graph (i.e. `isRoot()` is true for this table)
     */
    getPluginRootTables(table: string): Set<string>;
    /**
     * Checks if a table is a plugin entry-point (declared as a root by any plugin).
     * Used to determine if a warning should be shown when transforming a non-root table.
     * @param table - The table name to check
     * @returns True if the table is a plugin root, false otherwise
     */
    isPluginRootTable(table: string): boolean;
}
export {};
