import { IKosModelContainer } from '../core/kos-container-model';
import { IKosDataModel, IKosDataModelCreator, KosCreationContext } from '../core/kosModel';
export interface ModelFactory<T extends IKosDataModel, O extends Object = {}> {
    build: (modelId?: string, options?: O) => T;
    buildAsync: (modelId?: string, options?: O) => Promise<T>;
    type: string;
}
export interface IKosModelHolder<T extends IKosDataModel = IKosDataModel> extends IKosDataModel {
    readonly models: IKosModelContainer<T>;
    data: T[];
    addModel: (model: T) => void;
    removeModel: (id: string) => void;
    getModel: (id: string) => T | undefined;
}
export interface KosModelRegistrationFactory {
    factory: ModelFactory<IKosDataModel>;
}
export interface KosSingletonModelBaseRegistration {
    singleton: true;
}
export interface KosIdentifiableModelBaseRegistration {
    singleton: false;
}
export interface KosModelClassRegistration<T extends IKosDataModel, O extends object = Record<string, any>> extends KosIdentifiableModelBaseRegistration {
    class: new (modelId: string, options: O, context: KosCreationContext) => T;
}
export interface KosModelFactoryRegistration<T extends IKosDataModel, O extends object = Record<string, any>> extends KosIdentifiableModelBaseRegistration {
    create: IKosDataModelCreator<T, O>;
}
export interface KosSingletonModelClassRegistration<T extends IKosDataModel, O extends object = Record<string, any>> extends KosSingletonModelBaseRegistration {
    class: new (modelId: string, options: O, context: KosCreationContext) => T;
}
export interface KosSingletonModelFactoryRegistration<T extends IKosDataModel, O extends object = Record<string, any>> extends KosSingletonModelBaseRegistration {
    create: IKosDataModelCreator<T, O>;
}
export type KosIdentifiableModelRegistration<T extends IKosDataModel, O extends object = Record<string, any>> = KosModelClassRegistration<T, O> | KosModelFactoryRegistration<T, O>;
export type KosSingletonModelRegistration<T extends IKosDataModel, O extends object = Record<string, any>> = KosSingletonModelClassRegistration<T, O> | KosSingletonModelFactoryRegistration<T, O>;
export type KosModelRegistration<T extends IKosDataModel, O extends object = Record<string, any>> = KosIdentifiableModelRegistration<T, O> | KosSingletonModelRegistration<T, O>;
export type SingletonFactory<T extends IKosDataModel, O extends object = Record<string, any>> = (options?: O, parentId?: string) => T;
export type IdentifiableModelFactory<T extends IKosDataModel, O extends object = Record<string, any>> = (id: string) => (options?: O, parentId?: string) => T;
export type ModelFactoryRegistration<T extends IKosDataModel, O extends object = Record<string, any>> = SingletonFactory<T, O> | IdentifiableModelFactory<T, O>;
export interface BaseKosModelRegistrationBean<T extends IKosDataModel, O extends object = Record<string, any>> {
    registration: {
        [k: string]: KosModelRegistration<T, O>;
    };
    type: string;
    /**
     * [Typescript type predicate](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates) function that will identify and narrow down a model to a .
  
     * @example
     * ```typescript
     *
     * const model: IKosDataModel = ...; // some model
     *
     * if (Beverage.predicate(model)) {
     *    // if the function evaluates to true, the model is narrowed down to AvailabilityModel
     *    // and the compiler will know that the model has the AvailabilityModel interface
     *    model.updateAvailability(false);
     * }
     * ```
     * @typeParam T the type of the KOS Model
     * **/
    predicate: (model: IKosDataModel) => model is T;
    factory: ModelFactoryRegistration<T, O>;
}
/**
 * KosModelRegistrationBean
 * **/
export interface KosModelRegistrationBean<T extends IKosDataModel, O extends object = Record<string, any>> extends BaseKosModelRegistrationBean<T, O> {
    registration: {
        [k: string]: KosIdentifiableModelRegistration<T, O> & {
            factory?: IdentifiableModelFactory<T, O>;
        };
    };
    /**
     *
     * The factory method creates a factory function that can be used to create new model instances.
     *
     * The factory function is a curried function that takes the model id as the first argument and the options as the second argument.
     *
     * If a model with the specified id already exists, the factory function will return the existing model.  The options will be ignored
     * in this case and the existing model will be returned in its current state.
     *
     */
    factory: IdentifiableModelFactory<T, O>;
}
export interface SingletonKosModelRegistrationBean<T extends IKosDataModel, O extends object = Record<string, any>> extends BaseKosModelRegistrationBean<T, O> {
    registration: {
        [k: string]: KosSingletonModelRegistration<T, O> & {
            factory?: SingletonFactory<T, O>;
        };
    };
    factory: SingletonFactory<T, O>;
}
export type PublicInterface<T> = {
    [P in keyof T]: T[P];
};
export type PublicModelInterface<T> = Omit<PublicInterface<T>, "">;
//# sourceMappingURL=model.d.ts.map