import { Layout } from '@coral-xyz/borsh';
/**
 * An object literal specifying *all* "update mode" enum values (of type {@code M}) and their corresponding config items
 * (belonging to a top-level config struct {@code C}).
 *
 * An instance of this type is needed to construct a {@link ConfigUpdater}, as shown below.
 *
 * @example
 * ```
 * // Define the updater using a "map" - the line below would NOT compile if you forgot about any `StarWarsUpdateMode`:
 * const STAR_WARS_UPDATER = new ConfigUpdater(StarWarsUpdateMode.fromDecoded, StarWars, (config) => ({
 *   [StarWarsUpdateMode.ANewHope.kind]: config.aNewHope,
 *   [StarWarsUpdateMode.TheEmpireStrikesBack.kind]: config.theEmpireStrikesBack,
 *   [StarWarsUpdateMode.ReturnOfTheJedi.kind]: config.returnOfTheJedi,
 * }));
 * ```
 */
export type ConfigItemMap<M extends BorshEnum, C> = BorshEnumMap<M, SingleOrArray<ConfigItem<C, any>>>;
/**
 * As advertised.
 */
export type SingleOrArray<T> = T | T[];
/**
 * A set of everything required to create an update ix for a single config item of type {@code A} belonging to a
 * config object of type {@code C}.
 */
export type ConfigItem<C, A> = {
    readonly __layout: Layout<A>;
    readonly __getter: Getter<C, A>;
};
/**
 * A {@link ConfigItem} representing a borsh structure.
 *
 * Such structure may be used:
 * - either directly (i.e. a borsh-serialized "fat" config item, e.g. `ReserveConfig.borrowRateCurve`),
 * - or just to access its fields (e.g. `ReserveConfig.tokenInfo.pythConfiguration.price`).
 */
export type StructConfigItem<C, A extends Record<string, any>> = ConfigItem<C, A> & {
    [K in keyof A]: A[K] extends object ? StructConfigItem<C, A[K]> : ConfigItem<C, A>;
};
/**
 * A syntactic sugar allowing for auto-completion of values within {@link ConfigItemMap}.
 */
export type AnyConfigItem<C, A> = A extends Record<string, any> ? StructConfigItem<C, A> : ConfigItem<C, A>;
/**
 * A composite {@link ConfigItem}, allowing to encode multiple fields together.
 *
 * @example
 * ```
 *   ...
 *   [CartoonsUpdateMode.UpdateTomAndJerry.discriminator]: new CompositeConfigItem(
 *     CARTOONS.value().characters.cats.tom,
 *     CARTOONS.value().characters.rodents.jerry
 *   ),
 *   ...
 * ```
 */
export declare class CompositeConfigItem<C> implements ConfigItem<C, Record<string, any>> {
    readonly __layout: Layout<Record<string, any>>;
    readonly __getter: Getter<C, Record<string, any>>;
    constructor(...components: AnyConfigItem<C, any>[]);
}
/**
 * Creates an array of config items - one per each element of the given array.
 *
 * An example use-case is `LendingMarket.elevationGroups[]`: to update all of them, we need N ixs:
 * - `updateLendingMarket(mode = ElevationGroup, value = elevationGroups[0])`
 * - `updateLendingMarket(mode = ElevationGroup, value = elevationGroups[1])`
 * - `updateLendingMarket(mode = ElevationGroup, value = elevationGroups[2])`
 * ...
 *
 * So: conceptually, the *array* is not "a config item". Each *slot* in that array is its own config item.
 */
export declare function arrayElementConfigItems<C, A>(arrayConfigItem: ConfigItem<C, A[]>): ConfigItem<C, A>[];
/**
 * A constructor reference of a borsh structure.
 */
export interface BorshStructClass<C> {
    new (...args: any[]): C;
    layout: any;
}
/**
 * A missing common type for borsh enums, which borsh should really have provided itself.
 */
export interface BorshEnum {
    kind: string;
}
/**
 * A part of a {@link ConfigUpdater} responsible for a single config item.
 */
export declare class ConfigItemUpdater<C, A> {
    private readonly item;
    constructor(item: ConfigItem<C, A>);
    /**
     * Returns a serialized value of the specific config item extracted from the given top-level {@code newConfig}, or
     * `undefined` if the value has not changed from the given {@code currentConfig}.
     */
    encodeUpdatedItemFrom(currentConfig: C | undefined, newConfig: C): Uint8Array | undefined;
    /**
     * Borsh-serializes the given value.
     *
     * Only exposed for some legacy callers which still construct the update ixs manually (in tests).
     */
    encodeItem(item: A): Uint8Array;
}
/**
 * A resolver of config item changes.
 */
export declare class ConfigUpdater<M extends BorshEnum, C> {
    private readonly itemUpdaters;
    /**
     * A resolving constructor.
     *
     * The inputs:
     * - `fromDecoded`: a reference to the codegen'ed enum-decoding function, e.g. `UpdateConfigMode.fromDecoded`. Needed
     *   to turn the `<enumClass>.kind` strings into enums (i.e. instances of `M`).
     * - `configClass`: a reference to the codegen'ed top-level config class, e.g. `ReserveConfig`. Need to create a
     *    completion helper for the `itemMapBuilder`.
     * - `itemMapBuilder`: a function building a {@link ConfigItemMap} using the completion helper provided as its
     *    argument, e.g. `(config) => ({[UpdateLendingMarketMode.UpdateImmutableFlag.kind]: config.immutable, ...})`.
     *
     * See the usage example at {@link ConfigItemMap}.
     */
    constructor(fromDecoded: (mode: any) => M, configClass: BorshStructClass<C>, itemMapBuilder: (config: AnyConfigItem<C, C>) => ConfigItemMap<M, C>);
    /**
     * Returns all changes between the given current and new configs - in particular, this will be *all* supported fields'
     * changes if the previous config does not exist.
     *
     * Please note that more than one {@link EncodedConfigUpdate}s can be associated with a single `M` enum value (in
     * cases where e.g. an array property is updated by individual updates of its elements).
     */
    encodeAllUpdates(currentConfig: C | undefined, newConfig: C): EncodedConfigUpdate<M>[];
    /**
     * Gets the single updater of the given config item.
     *
     * Throws an error if the updates are not supported (e.g. for deprecated modes) or if the given item is handled by
     * multiple updaters (e.g. for an array property) - to handle these cases, use {@link allForMode()}.
     */
    forMode(mode: M): ConfigItemUpdater<C, any>;
    /**
     * Gets all the updaters of the given config item.
     *
     * This may be an empty array (e.g. for deprecated modes), or multiple elements (e.g. if an array property is updated
     * by individual updates of its elements). If you expect a single updater, use {@link forMode()}.
     */
    allForMode(mode: M): ConfigItemUpdater<C, any>[];
}
/** Reserve config fields have cross-dependencies with each other.
 *
 * When several fields must be updated at once, this will ensure
 * all intermediary states are valid.
 */
export declare class PriorityOrderedConfigUpdater<M extends BorshEnum, C> {
    private readonly updater;
    constructor(updater: ConfigUpdater<M, C>);
    encodeAllUpdates(currentConfig: C | undefined, newConfig: C, priorityOf: (mode: M) => number): EncodedConfigUpdate<M>[];
}
/**
 * The update mode discriminator and the serialized value needed to construct an update ix.
 */
export type EncodedConfigUpdate<M extends BorshEnum> = {
    mode: M;
    value: Uint8Array;
};
/**
 * Borsh-serializes the given value according to the given layout.
 *
 * Only exposed for some legacy callers which still construct the update ixs manually (in tests).
 */
export declare function encodeUsingLayout<T>(layout: Layout<T>, value: T): Uint8Array;
type BorshEnumMap<M extends BorshEnum, T> = {
    [Key in M['kind']]: T;
};
type Getter<C, A> = (config: C) => A;
export {};
//# sourceMappingURL=configItems.d.ts.map