import { MetaType } from './metaTypeCreator';
import { OriWhereFilterOp, OriOrderByDirection } from './ori';
import { ErrorLimitToLastOrderBy, ErrorWhereOrderByAndInEquality, ErrorWhereCompareValueMustBeArray, ErrorWhereOrderByEquality, ErrorWhereNotInArrayContainsAny, ErrorWhereNotInNotEqual, ErrorWhereArrayContainsArrayContainsAny, ErrorWhereInequalityOpStrSameField, ErrorWhereOnlyOneNotEqual, ErrorCursorTooManyArguments, ErrorWhereNoNeverEmptyArray, ErrorCursor__name__ } from './error';
import { IsSame } from './utils';
import { QueryConstraints, WhereConstraint, OrderByConstraint, CursorConstraint, LimitConstraint } from './queryConstraints';
import { Query } from './refs';
import { GetCorrectDocumentIdBasedOnRef, RemoveSentinelFieldPathFromCompare, __name__ } from './fieldPath';
import { CursorType } from './cursor';
import { QueryDocumentSnapshot, DocumentSnapshot } from './snapshot';
declare type Equal = '==';
declare type Greater = '>';
declare type Smaller = '<';
declare type GreaterEqual = '>=';
declare type SmallerEqual = '<=';
declare type Range = Greater | Smaller | Greater | GreaterEqual | SmallerEqual;
declare type NotEqual = '!=';
declare type NotIn = 'not-in';
declare type In = 'in';
declare type ArrayContains = 'array-contains';
declare type ArrayContainsAny = 'array-contains-any';
declare type InequalityOpStr = Range | NotEqual | NotIn;
declare type ValueOfOptStr = Range | NotEqual | Equal;
declare type ArrayOfOptStr = In | NotIn;
declare type ValueOfOnlyArrayOptStr = ArrayContainsAny;
declare type ElementOfOptStr = ArrayContains;
declare type ValidateOrderByAndInequalityWhere<T extends MetaType, AllQCs extends QueryConstraints<T>[]> = GetFirstInequalityWhere<T, AllQCs> extends infer W ? W extends WhereConstraint<T, string, InequalityOpStr, unknown> ? GetFirstOrderBy<T, AllQCs> extends infer O ? O extends OrderByConstraint<string, OriOrderByDirection | undefined> ? IsSame<W['fieldPath'], O['fieldPath']> extends true ? true : ErrorWhereOrderByAndInEquality<O['fieldPath'], W['fieldPath']> : true : never : true : never;
export declare type QueryConstraintLimitation<T extends MetaType, Q extends Query<T>, RestQCs extends QueryConstraints<T>[], PreviousQCs extends QueryConstraints<T>[], AllQCs extends QueryConstraints<T>[]> = ValidateOrderByAndInequalityWhere<T, AllQCs> extends string ? ValidateOrderByAndInequalityWhere<T, AllQCs> : RestQCs extends [infer Head, ...infer Rest] ? Rest extends QueryConstraints<T>[] ? [
    Head extends LimitConstraint<'limit', number> ? Head : Head extends OrderByConstraint<string, OriOrderByDirection | undefined> ? OrderByConstraintLimitation<T, Head, AllQCs> : Head extends LimitConstraint<'limitToLast', number> ? LimitToLastConstraintLimitation<T, Head, AllQCs> : Head extends WhereConstraint<T, string, OriWhereFilterOp, unknown> ? WhereConstraintLimitation<T, Q, Head, PreviousQCs> : Head extends CursorConstraint<CursorType, unknown[]> ? CursorConstraintLimitation<T, Head, PreviousQCs> : never,
    ...QueryConstraintLimitation<T, Q, Rest, Head extends QueryConstraints<T> ? [...PreviousQCs, Head] : PreviousQCs, // impossible route
    AllQCs>
] : never[] : RestQCs;
declare type ValidateCursorOrderBy<T extends MetaType, Values extends unknown[], AllOrderBy extends OrderByConstraint<string, OriOrderByDirection | undefined>[]> = Values extends [infer Head, ...infer Rest] ? AllOrderBy extends [infer H, ...infer R] ? H extends OrderByConstraint<string, OriOrderByDirection | undefined> ? [
    H['fieldPath'] extends __name__ ? string extends Head ? ErrorCursor__name__ : T['docPath'] : Head extends T['compare'][H['fieldPath']] | QueryDocumentSnapshot<T> | DocumentSnapshot<T> ? Head | QueryDocumentSnapshot<T> | DocumentSnapshot<T> : T['compare'][H['fieldPath']] | QueryDocumentSnapshot<T> | DocumentSnapshot<T>,
    ...ValidateCursorOrderBy<T, Rest, R extends OrderByConstraint<string, OriOrderByDirection | undefined>[] ? R : []>
] : never : [ErrorCursorTooManyArguments] : [];
declare type CursorConstraintLimitation<T extends MetaType, U extends CursorConstraint<CursorType, unknown[]>, PreviousQCs extends QueryConstraints<T>[]> = CursorConstraint<CursorType, ValidateCursorOrderBy<RemoveSentinelFieldPathFromCompare<T>, U['values'], GetAllOrderBy<T, PreviousQCs, []>>>;
declare type LimitToLastConstraintLimitation<T extends MetaType, U extends LimitConstraint<'limitToLast', number>, AllQCs extends QueryConstraints<T>[]> = AllQCs extends (infer A)[] ? A extends QueryConstraints<T> ? A['type'] extends 'orderBy' ? U : ErrorLimitToLastOrderBy : never : never;
declare type ValidateOrderByEqualityWhere<T extends MetaType, U extends OrderByConstraint<string, OriOrderByDirection | undefined>, AllQCs extends QueryConstraints<T>[]> = Extract<GetAllWhereConstraint<T, AllQCs, never>, WhereConstraint<T, U['fieldPath'], In | Equal, unknown>> extends never ? true : false;
declare type OrderByConstraintLimitation<T extends MetaType, U extends OrderByConstraint<string, OriOrderByDirection | undefined>, AllQCs extends QueryConstraints<T>[]> = ValidateOrderByEqualityWhere<T, U, AllQCs> extends false ? ErrorWhereOrderByEquality : U;
declare type ValidateWhereNotInArrayContainsAny<T extends MetaType, U extends WhereConstraint<T, string, OriWhereFilterOp, unknown>, PreviousQCs extends QueryConstraints<T>[]> = U['opStr'] extends In | NotIn | ArrayContainsAny ? Extract<GetAllWhereConstraintOpStr<T, PreviousQCs, never>, In | NotIn | ArrayContainsAny> extends never ? true : ErrorWhereNotInArrayContainsAny : true;
declare type ValidateWhereNotInNotEqual<T extends MetaType, U extends WhereConstraint<T, string, OriWhereFilterOp, unknown>, PreviousQCs extends QueryConstraints<T>[]> = U['opStr'] extends NotIn ? Extract<GetAllWhereConstraintOpStr<T, PreviousQCs, never>, NotEqual> extends never ? true : ErrorWhereNotInNotEqual : U['opStr'] extends NotEqual ? Extract<GetAllWhereConstraintOpStr<T, PreviousQCs, never>, NotIn> extends never ? Extract<GetAllWhereConstraintOpStr<T, PreviousQCs, never>, NotEqual> extends never ? true : ErrorWhereOnlyOneNotEqual : ErrorWhereNotInNotEqual : true;
declare type ValidateWhereArrayContainsArrayContainsAny<T extends MetaType, U extends WhereConstraint<T, string, OriWhereFilterOp, unknown>, PreviousQCs extends QueryConstraints<T>[]> = U['opStr'] extends ArrayContains ? Extract<GetAllWhereConstraintOpStr<T, PreviousQCs, never>, ArrayContains | ArrayContainsAny> extends never ? true : ErrorWhereArrayContainsArrayContainsAny : U['opStr'] extends ArrayContainsAny ? Extract<GetAllWhereConstraintOpStr<T, PreviousQCs, never>, ArrayContains> extends never ? true : ErrorWhereArrayContainsArrayContainsAny : true;
declare type ValidateWhereInequalityOpStrSameField<T extends MetaType, U extends WhereConstraint<T, string, OriWhereFilterOp, unknown>, PreviousQCs extends QueryConstraints<T>[]> = U['opStr'] extends InequalityOpStr ? Extract<GetAllWhereConstraint<T, PreviousQCs, never>, WhereConstraint<T, string, InequalityOpStr, unknown>> extends never ? true : Exclude<Extract<GetAllWhereConstraint<T, PreviousQCs, never>, WhereConstraint<T, string, InequalityOpStr, unknown>>, WhereConstraint<T, U['fieldPath'], InequalityOpStr, unknown>> extends never ? true : ErrorWhereInequalityOpStrSameField : true;
declare type WhereConstraintLimitation<T extends MetaType, Q extends Query<T>, U extends WhereConstraint<T, string, OriWhereFilterOp, unknown>, PreviousQCs extends QueryConstraints<T>[]> = ValidateWhereNotInArrayContainsAny<T, U, PreviousQCs> extends string ? ValidateWhereNotInArrayContainsAny<T, U, PreviousQCs> : ValidateWhereNotInNotEqual<T, U, PreviousQCs> extends string ? ValidateWhereNotInNotEqual<T, U, PreviousQCs> : ValidateWhereArrayContainsArrayContainsAny<T, U, PreviousQCs> extends string ? ValidateWhereArrayContainsArrayContainsAny<T, U, PreviousQCs> : ValidateWhereInequalityOpStrSameField<T, U, PreviousQCs> extends string ? ValidateWhereInequalityOpStrSameField<T, U, PreviousQCs> : U['opStr'] extends ValueOfOptStr ? WhereConstraint<T, U['fieldPath'], U['opStr'], GetCorrectDocumentIdBasedOnRef<T, Q, U['fieldPath'], U['value']>> : U['opStr'] extends ArrayOfOptStr ? WhereConstraint<T, U['fieldPath'], U['opStr'], U['value'] extends never[] ? ErrorWhereNoNeverEmptyArray : U['value'] extends (infer P)[] ? GetCorrectDocumentIdBasedOnRef<T, Q, U['fieldPath'], P>[] : ErrorWhereCompareValueMustBeArray<U['fieldPath']>> : U['opStr'] extends ValueOfOnlyArrayOptStr ? WhereConstraint<T, U['fieldPath'], U['opStr'], U['value'] extends never[] ? ErrorWhereNoNeverEmptyArray : T['compare'][U['fieldPath']] extends unknown[] ? T['compare'][U['fieldPath']] : ErrorWhereCompareValueMustBeArray<U['fieldPath']>> : U['opStr'] extends ElementOfOptStr ? WhereConstraint<T, U['fieldPath'], U['opStr'], T['compare'][U['fieldPath']] extends (infer R)[] ? R : ErrorWhereCompareValueMustBeArray<U['fieldPath']>> : never;
declare type GetFirstInequalityWhere<T extends MetaType, QCs extends QueryConstraints<T>[]> = QCs extends [infer H, ...infer Rest] ? H extends WhereConstraint<T, string, InequalityOpStr, unknown> ? H : Rest extends QueryConstraints<T>[] ? GetFirstInequalityWhere<T, Rest> : never : true;
declare type GetFirstOrderBy<T extends MetaType, QCs extends QueryConstraints<T>[]> = QCs extends [infer H, ...infer Rest] ? H extends OrderByConstraint<string, OriOrderByDirection | undefined> ? H : Rest extends QueryConstraints<T>[] ? GetFirstOrderBy<T, Rest> : never : true;
declare type GetAllOrderBy<T extends MetaType, QCs extends QueryConstraints<T>[], AllOrderBy extends OrderByConstraint<string, OriOrderByDirection | undefined>[]> = QCs extends [infer H, ...infer Rest] ? Rest extends QueryConstraints<T>[] ? GetAllOrderBy<T, Rest, H extends OrderByConstraint<string, OriOrderByDirection | undefined> ? [...AllOrderBy, H] : AllOrderBy> : [] : AllOrderBy;
declare type GetAllWhereConstraint<T extends MetaType, QCs extends QueryConstraints<T>[], WhereConstraintsAcc extends WhereConstraint<T, string, OriWhereFilterOp, unknown>> = QCs extends [infer H, ...infer R] ? R extends QueryConstraints<T>[] ? WhereConstraintsAcc | GetAllWhereConstraint<T, R, (H extends WhereConstraint<T, string, OriWhereFilterOp, unknown> ? H : never) | WhereConstraintsAcc> : WhereConstraintsAcc : WhereConstraintsAcc;
declare type GetAllWhereConstraintOpStr<T extends MetaType, QCs extends QueryConstraints<T>[], OpStrAcc extends OriWhereFilterOp> = QCs extends [infer H, ...infer R] ? R extends QueryConstraints<T>[] ? OpStrAcc | GetAllWhereConstraintOpStr<T, R, (H extends WhereConstraint<T, string, OriWhereFilterOp, unknown> ? H['opStr'] : never) | OpStrAcc> : OpStrAcc : OpStrAcc;
export {};
