import { type ComponentUpgradeMigrationStep } from './component-upgrade-rules-types.js';
export { type ComponentUpgradeMigrationStep } from './component-upgrade-rules-types.js';
/**
 * Static utility for loading component migration rules and planning upgrade paths.
 */
export declare class ComponentUpgradeMigrationRules {
    /**
     * Module-level cache for the loaded migration config. Once loaded (from file or embedded
     * defaults), the config is stored here to avoid redundant file I/O on subsequent calls.
     * Reset via `resetUpgradeMigrationConfigCache()` in tests.
     */
    private static cachedConfig;
    /**
     * Resets the cached migration config. Intended for use in tests only.
     *
     * This allows tests to:
     * - Switch between different config files between test cases.
     * - Force re-loading to verify file parsing behavior.
     * - Ensure test isolation (no state leaks between test cases).
     */
    static resetCache(): void;
    /**
     * Plans the complete upgrade migration path for a component.
     *
     * This is the main entry point of the module. Given a component name, current version, and
     * target version, it returns an ordered list of migration steps that the caller should
     * execute sequentially to safely upgrade the component.
     *
     * ## Behavior by scenario
     *
     * ### Downgrade or same-version (current >= target)
     * Returns a single step using the component's default strategy. No boundary analysis is
     * performed since boundaries only apply to forward upgrades.
     *
     * ### Forward upgrade with no boundaries crossed
     * Returns a single step using the default strategy (typically `'in-place'`).
     *
     * ### Forward upgrade crossing one or more boundaries
     * Returns multiple steps, one per boundary group (after merging consecutive same-strategy
     * boundaries). The last boundary's step targets the final `targetVersion` (not the boundary
     * version itself). If there's remaining distance after all boundaries, a final default-
     * strategy step covers the gap.
     *
     * ## Example migration plans
     *
     * **Current config** — default `'in-place'`, `'recreate'` boundary at `0.28.1`:
     *
     * ```
     * planUpgradeMigrationPath('block-node', '0.28.0', '0.28.1')
     * → [{ from: '0.28.0', to: '0.28.1', strategy: 'recreate' }]
     * // Boundary at 0.28.1 crossed; step targets the final version directly.
     *
     * planUpgradeMigrationPath('block-node', '0.28.0', '0.35.0')
     * → [{ from: '0.28.0', to: '0.35.0', strategy: 'recreate' }]
     * // Boundary at 0.28.1 crossed; last boundary so step jumps to target (0.35.0).
     *
     * planUpgradeMigrationPath('block-node', '0.28.1', '0.35.0')
     * → [{ from: '0.28.1', to: '0.35.0', strategy: 'in-place' }]
     * // Already at/past 0.28.1; no boundary crossed → default in-place.
     * ```
     *
     * **Hypothetical addition** — adding a second `'recreate'` boundary at 0.29.0:
     *
     * ```
     * // Config: boundaries: [{ version: '0.28.1', recreate }, { version: '0.29.0', recreate }]
     *
     * planUpgradeMigrationPath('block-node', '0.28.0', '0.29.0')
     * → [{ from: '0.28.0', to: '0.29.0', strategy: 'recreate' }]
     * // Both boundaries have 'recreate' → merged into 1 step; last boundary targets final version.
     *
     * planUpgradeMigrationPath('block-node', '0.28.1', '0.29.0')
     * → [{ from: '0.28.1', to: '0.29.0', strategy: 'recreate' }]
     * // Only the 0.29.0 boundary crossed → 1 recreate step.
     * ```
     *
     * @param component - Component name (e.g., 'block-node'). Must match a key in the config.
     * @param currentVersion - The currently installed version (semver string).
     * @param targetVersion - The desired target version (semver string).
     * @returns Ordered array of migration steps to execute.
     */
    static planUpgradeMigrationPath(component: string, currentVersion: string, targetVersion: string): ComponentUpgradeMigrationStep[];
    /**
     * Loads the component upgrade migration configuration.
     *
     * Loading priority:
     * 1. Return cached config if already loaded (performance optimization).
     * 2. Try to read and parse the external JSON override file at `constants.UPGRADE_MIGRATIONS_FILE`.
     *    This allows operators to customize migration rules without modifying source code.
     * 3. If the file doesn't exist or fails to parse, silently fall back to a safe empty config
     *    (`{components: {}}`). Unknown components then receive an `'in-place'` default with no boundaries.
     *
     * The fallback behavior is intentional: we never want a missing or malformed config file to
     * block upgrades entirely. The resource-backed defaults always provide a safe baseline.
     *
     * Historical note: before this refactor, the default config lived in the deleted
     * `DEFAULT_COMPONENT_UPGRADE_MIGRATION_CONFIG` constant. The contents now live in
     * `resources/component-upgrade-migrations.json` and are loaded dynamically at runtime.
     */
    private static loadConfig;
    /**
     * Retrieves the migration config for a specific component by name.
     *
     * If the component has no entry in the config (e.g., a newly added component that hasn't
     * had any migration rules defined yet), returns a safe default: `'in-place'` strategy with
     * no boundaries. This means unknown components always get a simple Helm upgrade.
     *
     * @param component - The component name (e.g., 'block-node').
     * @returns The component's migration config, or a default no-op config.
     */
    private static getComponentConfig;
    /**
     * Finds all boundary rules that are "crossed" during a forward upgrade from `current` to `target`.
     *
     * A boundary is "crossed" when:
     *   current < boundary.version <= target
     *
     * This means:
     * - If you're already AT or ABOVE the boundary version, it's not crossed (you've already
     *   passed it in a previous upgrade).
     * - If the target is BELOW the boundary version, it's not crossed (you haven't reached it yet).
     *
     * After finding crossed boundaries, they are:
     * 1. Sorted ascending by version (so the earliest boundary is processed first).
     * 2. **Reduced (merged)**: consecutive boundaries with the SAME strategy are collapsed into
     *    one entry (keeping the later version). This optimization avoids unnecessary intermediate
     *    steps. For example, if boundaries at 0.28.0 and 0.30.0 both require `'recreate'`, there's
     *    no point recreating at 0.28.0 and then recreating again at 0.30.0 — we can skip straight
     *    to 0.30.0 with a single recreate.
     *
     * @param componentConfig - The component's migration config containing boundary rules.
     * @param current - The current installed version (parsed SemanticVersion<string>).
     * @param target - The desired target version (parsed SemanticVersion<string>).
     * @returns Sorted and reduced array of crossed boundary rules.
     */
    private static findCrossedBoundaries;
}
