import { ConstantFilter } from './ConstantFilter';
import { Patient } from '../../icc-api/model/Patient';
import { AbstractFilterPatient } from '../../icc-api/model/AbstractFilterPatient';
import { AbstractFilterContact } from '../../icc-api/model/AbstractFilterContact';
import { AbstractFilterService } from '../../icc-api/model/AbstractFilterService';
import { Service } from '../../icc-api/model/Service';
import { Contact } from '../../icc-api/model/Contact';
import { IntersectionFilter } from './IntersectionFilter';
import { UnionFilter } from './UnionFilter';
import { ComplementFilter } from './ComplementFilter';
import GenderEnum = Patient.GenderEnum;
import { Device } from '../../icc-api/model/Device';
import { AbstractFilterDevice } from '../../icc-api/model/AbstractFilterDevice';
import { MaintenanceTask } from '../../icc-api/model/MaintenanceTask';
import { AbstractFilterMaintenanceTask } from '../../icc-api/model/AbstractFilterMaintenanceTask';
import { Code } from '../../icc-api/model/Code';
import { AbstractFilterCode } from '../../icc-api/model/AbstractFilterCode';
import { HealthElement } from '../../icc-api/model/HealthElement';
import { AbstractFilterHealthElement } from '../../icc-api/model/AbstractFilterHealthElement';
import { Invoice } from '../../icc-api/model/Invoice';
import { AbstractFilterInvoice } from '../../icc-api/model/AbstractFilterInvoice';
import { User } from '../../icc-api/model/User';
import { AbstractFilterUser } from '../../icc-api/model/AbstractFilterUser';
import { HealthcareParty } from '../../icc-api/model/HealthcareParty';
import { AbstractFilterHealthcareParty } from '../../icc-api/model/AbstractFilterHealthcareParty';
import { Tarification } from '../../icc-api/model/Tarification';
import { AbstractFilterPricing } from '../../icc-api/model/AbstractFilterPricing';
import { Insurance } from '../../icc-api/model/Insurance';
import { AbstractFilterInsurance } from '../../icc-api/model/AbstractFilterInsurance';
export * from './AllCodesFilter';
export * from './AllDevicesFilter';
export * from './AllDocumentsFilter';
export * from './AllHealthcarePartiesFilter';
export * from './AllInsurancesFilter';
export * from './AllUsersFilter';
export * from './AllPricingFilter';
export * from './CodeByIdsFilter';
export * from './CodeByRegionTypeCodeVersionFilter';
export * from './CodeByRegionTypeLabelLanguageFilter';
export * from './ComplementFilter';
export * from './ConstantFilter';
export * from './ContactByHcPartyFilter';
export * from './ContactByHcPartyPatientTagCodeDateFilter';
export * from './ContactByHcPartyTagCodeDateFilter';
export * from './ContactByServiceIdsFilter';
export * from './DeviceByHcPartyFilter';
export * from './DeviceByIdsFilter';
export * from './HealthElementByHcPartyCodeFilter';
export * from './HealthElementByHcPartyFilter';
export * from './HealthElementByHcPartyIdentifiersFilter';
export * from './HealthElementByHcPartyIdentifiersVersioningFilter';
export * from './HealthElementByHcPartySecretForeignKeysFilter';
export * from './HealthElementByHcPartyStatusVersioningFilter';
export * from './HealthElementByHcPartyTagCodeFilter';
export * from './HealthElementByHcPartyTagFilter';
export * from './HealthElementByIdsFilter';
export * from './HealthcarePartyByIdsFilter';
export * from './HealthcarePartyByNameFilter';
export * from './HealthcarePartyByTagCodeFilter';
export * from './HealthcarePartyByIdentifiersFilter';
export * from './HealthcarePartyByIdsFilter';
export * from './IntersectionFilter';
export * from './InvoiceByHcPartyCodeDateFilter';
export * from './PatientByHcPartyAndActiveFilter';
export * from './PatientByHcPartyAndAddressFilter';
export * from './PatientByHcPartyAndExternalIdFilter';
export * from './PatientByHcPartyAndIdentifiersFilter';
export * from './PatientByHcPartyAndSsinFilter';
export * from './PatientByHcPartyAndSsinsFilter';
export * from './PatientByHcPartyDateOfBirthBetweenFilter';
export * from './PatientByHcPartyDateOfBirthFilter';
export * from './PatientByHcPartyFilter';
export * from './PatientByHcPartyGenderEducationProfessionFilter';
export * from './PatientByHcPartyNameContainsFuzzyFilter';
export * from './PatientByHcPartyNameFilter';
export * from './PatientByIdsFilter';
export * from './ServiceByContactsAndSubcontactsFilter';
export * from './ServiceByHcPartyFilter';
export * from './ServiceByHcPartyIdentifiersFilter';
export * from './ServiceByHcPartyHealthElementIdsFilter';
export * from './ServiceByHcPartyTagCodeDateFilter';
export * from './ServiceByHcPartyCodePrefixFilter';
export * from './ServiceByHcPartyTagPrefixFilter';
export * from './ServiceByHcPartyMonthCodePrefixFilter';
export * from './ServiceByHcPartyMonthTagPrefixFilter';
export * from './ServiceByHcPartyPatientCodePrefixFilter';
export * from './ServiceByHcPartyPatientTagPrefixFilter';
export * from './ServiceByHcPartyCodesFilter';
export * from './ServiceByHcPartyTagCodesFilter';
export * from './ServiceByHcPartyPatientCodesFilter';
export * from './ServiceByHcPartyPatientTagCodesFilter';
export * from './ServiceByIdsFilter';
export * from './ServiceBySecretForeignKeys';
export * from './UnionFilter';
export * from './UserByIdsFilter';
export * from './MaintenanceTaskByHcPartyAndIdentifiersFilter';
export * from './MaintenanceTaskByHcPartyAndTypeFilter';
export * from './MaintenanceTaskByIdsFilter';
export * from './MaintenanceTaskAfterDateFilter';
export * from './TopicByHcPartyFilter';
export * from './TopicByParticipantFilter';
export * from './MessageByHcPartyFilter';
export * from './MessageByHcPartyTransportGuidFilter';
export * from './LatestMessageByHcPartyTransportGuidFilter';
export declare class Filter {
    static patient(): PatientFilterBuilder;
}
export type AbstractFilter<T> = (T extends Patient ? AbstractFilterPatient : T extends Contact ? AbstractFilterContact : T extends Service ? AbstractFilterService : T extends HealthcareParty ? AbstractFilterHealthcareParty : T extends Device ? AbstractFilterDevice : T extends MaintenanceTask ? AbstractFilterMaintenanceTask : T extends Code ? AbstractFilterCode : T extends HealthElement ? AbstractFilterHealthElement : T extends Insurance ? AbstractFilterInsurance : T extends Invoice ? AbstractFilterInvoice : T extends User ? AbstractFilterUser : T extends Tarification ? AbstractFilterPricing : never) | ConstantFilter<T> | IntersectionFilter<T> | UnionFilter<T> | ComplementFilter<T>;
declare abstract class FilterBuilder<T> {
    filterProvider?: () => AbstractFilter<T>;
    protected constructor(filterProvider?: () => AbstractFilter<T>, composer?: (thisFilterBuilder: FilterBuilder<T>, otherFilterBuilder: FilterBuilder<T>) => FilterBuilder<T>);
    composer: (thisFilterBuilder: FilterBuilder<T>, otherFilterBuilder: FilterBuilder<T>) => FilterBuilder<T>;
    abstract build(): AbstractFilter<T>;
    abstract clone(filterProvider?: () => AbstractFilter<T>, composer?: (thisFilterBuilder: FilterBuilder<T>, otherFilterBuilder: FilterBuilder<T>) => FilterBuilder<T>): FilterBuilder<T>;
    listOf(elements: T[]): FilterBuilder<T>;
    /**
     * There are two ways of doing and, or, …
     *
     * 1) for (...) or (...) we use the syntax ... .or((builder) => builder...)
     * ex: youngerThan(65).or((b) => b.olderThan(18).and().gender(M)) means any gender < 65 or male > 18
     * 2) for ((...) or ...) we use the syntax ... .or().…
     * ex: youngerThan(65).or().olderThan(18).and().gender(M) means males between 18 and 65
     *
     * When 1) is used we do not have to wait for anything to provide a resolved builder that can later be combined with extra elements in the chain.
     * In other words, we can build the current filter chain up to the or/and/… and we can build what is inside the or/and/… brackets and we can set
     * the filterProvider of the returned Builder to () => UnionFilter([leftHand.build(), innerBrackets.build()]).
     *
     * When 2) is used, things get more tricky because we will have to do an or/and/… between what we have on the leftHand and with what we do not have
     * yet on the right hand. What we do in that situation is to set the filterProvider() to undefined because calling build() without having provided a
     * rightHand doesn't make sense. We set a composer that is going to be called the next time we chain a filter.
     *
     * @param filterBuilderFactory
     */
    and(filterBuilderFactory?: (it: FilterBuilder<T>) => FilterBuilder<T>): FilterBuilder<T>;
    or(filterBuilderFactory?: (it: FilterBuilder<T>) => FilterBuilder<T>): FilterBuilder<T>;
    minus(filterBuilderFactory?: (it: FilterBuilder<T>) => FilterBuilder<T>): FilterBuilder<T>;
    private makeLazyLeftRightFilterBuilder;
    private makeEagerLeftRightFilterBuilder;
}
declare class PatientFilterBuilder extends FilterBuilder<Patient> {
    hcpId?: string;
    constructor(filterProvider?: () => AbstractFilter<Patient>, hcpId?: string, composer?: (thisFilterBuilder: FilterBuilder<Patient>, otherFilterBuilder: FilterBuilder<Patient>) => FilterBuilder<Patient>);
    clone(filterProvider?: () => AbstractFilter<Patient>, composer?: (thisFilterBuilder: FilterBuilder<Patient>, otherFilterBuilder: FilterBuilder<Patient>) => FilterBuilder<Patient>): FilterBuilder<Patient>;
    listOf(elements: Patient[]): PatientFilterBuilder;
    and(filterBuilderFactory?: (it: PatientFilterBuilder) => PatientFilterBuilder): PatientFilterBuilder;
    or(filterBuilderFactory?: (it: PatientFilterBuilder) => PatientFilterBuilder): PatientFilterBuilder;
    minus(filterBuilderFactory?: (it: PatientFilterBuilder) => PatientFilterBuilder): PatientFilterBuilder;
    forHcp(hcpId: string): PatientFilterBuilder;
    all(): PatientFilterBuilder;
    activePatients(): PatientFilterBuilder;
    inactivePatients(): PatientFilterBuilder;
    byAddress(searchString?: string, postalCode?: string, houseNumber?: string): PatientFilterBuilder;
    withExternalId(externalId: string): PatientFilterBuilder;
    withSsins(ssins: string[]): PatientFilterBuilder;
    withDateOfBirthBetween(from?: number, to?: number): PatientFilterBuilder;
    byDateOfBirth(dateOfBirth: number): PatientFilterBuilder;
    olderThan(age: number): PatientFilterBuilder;
    youngerThan(age: number): PatientFilterBuilder;
    byGenderEducationProfession(gender?: GenderEnum, education?: string, profession?: string): PatientFilterBuilder;
    byIds(ids: string[]): PatientFilterBuilder;
    searchByName(name: string): PatientFilterBuilder;
    build(): AbstractFilter<Patient>;
}
