/**
 * Copyright 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import * as firestore from '@firebase/firestore-types';
import { FirebaseApp } from '@firebase/app-types';
import { FirebaseService } from '@firebase/app-types/private';
import { DatabaseId } from '../core/database_info';
import { FirestoreClient } from '../core/firestore_client';
import { Query as InternalQuery } from '../core/query';
import { Transaction as InternalTransaction } from '../core/transaction';
import { ViewSnapshot } from '../core/view_snapshot';
import { Document } from '../model/document';
import { DocumentKey } from '../model/document_key';
import { ResourcePath } from '../model/path';
import { AsyncQueue } from '../util/async_queue';
import { AnyJs } from '../util/misc';
import { FieldPath as ExternalFieldPath } from './field_path';
import { CompleteFn, ErrorFn, NextFn, PartialObserver, Unsubscribe } from './observer';
import { UserDataConverter } from './user_data_converter';
/**
 * Constant used to indicate the LRU garbage collection should be disabled.
 * Set this value as the `cacheSizeBytes` on the settings passed to the
 * `Firestore` instance.
 */
export declare const CACHE_SIZE_UNLIMITED = -1;
/**
 * Options that can be provided in the Firestore constructor when not using
 * Firebase (aka standalone mode).
 */
export interface FirestoreDatabase {
    projectId: string;
    database?: string;
}
/**
 * The root reference to the database.
 */
export declare class Firestore implements firestore.FirebaseFirestore, FirebaseService {
    private readonly _config;
    readonly _databaseId: DatabaseId;
    private _firestoreClient;
    readonly _queue: AsyncQueue;
    _dataConverter: UserDataConverter;
    constructor(databaseIdOrApp: FirestoreDatabase | FirebaseApp);
    settings(settingsLiteral: firestore.Settings): void;
    enableNetwork(): Promise<void>;
    disableNetwork(): Promise<void>;
    enablePersistence(settings?: firestore.PersistenceSettings): Promise<void>;
    ensureClientConfigured(): FirestoreClient;
    private configureClient(persistenceSettings);
    private static databaseIdFromApp(app);
    readonly app: FirebaseApp;
    INTERNAL: {
        delete: (options?: {
            purgePersistenceWithDataLoss?: boolean | undefined;
        } | undefined) => Promise<void>;
    };
    collection(pathString: string): firestore.CollectionReference;
    doc(pathString: string): firestore.DocumentReference;
    runTransaction<T>(updateFunction: (transaction: firestore.Transaction) => Promise<T>): Promise<T>;
    batch(): firestore.WriteBatch;
    static readonly logLevel: firestore.LogLevel;
    static setLogLevel(level: firestore.LogLevel): void;
    _areTimestampsInSnapshotsEnabled(): boolean;
}
/**
 * A reference to a transaction.
 */
export declare class Transaction implements firestore.Transaction {
    private _firestore;
    private _transaction;
    constructor(_firestore: Firestore, _transaction: InternalTransaction);
    get(documentRef: firestore.DocumentReference): Promise<firestore.DocumentSnapshot>;
    set(documentRef: firestore.DocumentReference, value: firestore.DocumentData, options?: firestore.SetOptions): Transaction;
    update(documentRef: firestore.DocumentReference, value: firestore.UpdateData): Transaction;
    update(documentRef: firestore.DocumentReference, field: string | ExternalFieldPath, value: AnyJs, ...moreFieldsAndValues: AnyJs[]): Transaction;
    delete(documentRef: firestore.DocumentReference): Transaction;
}
export declare class WriteBatch implements firestore.WriteBatch {
    private _firestore;
    private _mutations;
    private _committed;
    constructor(_firestore: Firestore);
    set(documentRef: firestore.DocumentReference, value: firestore.DocumentData, options?: firestore.SetOptions): WriteBatch;
    update(documentRef: firestore.DocumentReference, value: firestore.UpdateData): WriteBatch;
    update(documentRef: firestore.DocumentReference, field: string | ExternalFieldPath, value: AnyJs, ...moreFieldsAndValues: AnyJs[]): WriteBatch;
    delete(documentRef: firestore.DocumentReference): WriteBatch;
    commit(): Promise<void>;
    private verifyNotCommitted();
}
/**
 * A reference to a particular document in a collection in the database.
 */
export declare class DocumentReference implements firestore.DocumentReference {
    _key: DocumentKey;
    readonly firestore: Firestore;
    private _firestoreClient;
    constructor(_key: DocumentKey, firestore: Firestore);
    static forPath(path: ResourcePath, firestore: Firestore): DocumentReference;
    readonly id: string;
    readonly parent: firestore.CollectionReference;
    readonly path: string;
    collection(pathString: string): firestore.CollectionReference;
    isEqual(other: firestore.DocumentReference): boolean;
    set(value: firestore.DocumentData, options?: firestore.SetOptions): Promise<void>;
    update(value: firestore.UpdateData): Promise<void>;
    update(field: string | ExternalFieldPath, value: AnyJs, ...moreFieldsAndValues: AnyJs[]): Promise<void>;
    delete(): Promise<void>;
    onSnapshot(observer: PartialObserver<firestore.DocumentSnapshot>): Unsubscribe;
    onSnapshot(options: firestore.SnapshotListenOptions, observer: PartialObserver<firestore.DocumentSnapshot>): Unsubscribe;
    onSnapshot(onNext: NextFn<firestore.DocumentSnapshot>, onError?: ErrorFn, onCompletion?: CompleteFn): Unsubscribe;
    onSnapshot(options: firestore.SnapshotListenOptions, onNext: NextFn<firestore.DocumentSnapshot>, onError?: ErrorFn, onCompletion?: CompleteFn): Unsubscribe;
    private onSnapshotInternal(options, observer);
    get(options?: firestore.GetOptions): Promise<firestore.DocumentSnapshot>;
    private getViaSnapshotListener(resolve, reject, options?);
}
/**
 * Options interface that can be provided to configure the deserialization of
 * DocumentSnapshots.
 */
export interface SnapshotOptions extends firestore.SnapshotOptions {
}
export declare class DocumentSnapshot implements firestore.DocumentSnapshot {
    private _firestore;
    private _key;
    _document: Document | null;
    private _fromCache;
    private _hasPendingWrites;
    constructor(_firestore: Firestore, _key: DocumentKey, _document: Document | null, _fromCache: boolean, _hasPendingWrites: boolean);
    data(options?: firestore.SnapshotOptions): firestore.DocumentData | undefined;
    get(fieldPath: string | ExternalFieldPath, options?: firestore.SnapshotOptions): AnyJs;
    readonly id: string;
    readonly ref: firestore.DocumentReference;
    readonly exists: boolean;
    readonly metadata: firestore.SnapshotMetadata;
    isEqual(other: firestore.DocumentSnapshot): boolean;
    private convertObject(data, options);
    private convertValue(value, options);
    private convertArray(data, options);
}
export declare class QueryDocumentSnapshot extends DocumentSnapshot implements firestore.QueryDocumentSnapshot {
    constructor(firestore: Firestore, key: DocumentKey, document: Document, fromCache: boolean, hasPendingWrites: boolean);
    data(options?: SnapshotOptions): firestore.DocumentData;
}
export declare class Query implements firestore.Query {
    _query: InternalQuery;
    readonly firestore: Firestore;
    constructor(_query: InternalQuery, firestore: Firestore);
    where(field: string | ExternalFieldPath, opStr: firestore.WhereFilterOp, value: AnyJs): firestore.Query;
    orderBy(field: string | ExternalFieldPath, directionStr?: firestore.OrderByDirection): firestore.Query;
    limit(n: number): firestore.Query;
    startAt(docOrField: AnyJs | firestore.DocumentSnapshot, ...fields: AnyJs[]): firestore.Query;
    startAfter(docOrField: AnyJs | firestore.DocumentSnapshot, ...fields: AnyJs[]): firestore.Query;
    endBefore(docOrField: AnyJs | firestore.DocumentSnapshot, ...fields: AnyJs[]): firestore.Query;
    endAt(docOrField: AnyJs | firestore.DocumentSnapshot, ...fields: AnyJs[]): firestore.Query;
    isEqual(other: firestore.Query): boolean;
    /** Helper function to create a bound from a document or fields */
    private boundFromDocOrFields(methodName, docOrField, fields, before);
    /**
     * Create a Bound from a query and a document.
     *
     * Note that the Bound will always include the key of the document
     * and so only the provided document will compare equal to the returned
     * position.
     *
     * Will throw if the document does not contain all fields of the order by
     * of the query.
     */
    private boundFromDocument(methodName, doc, before);
    /**
     * Converts a list of field values to a Bound for the given query.
     */
    private boundFromFields(methodName, values, before);
    onSnapshot(observer: PartialObserver<firestore.QuerySnapshot>): Unsubscribe;
    onSnapshot(options: firestore.SnapshotListenOptions, observer: PartialObserver<firestore.QuerySnapshot>): Unsubscribe;
    onSnapshot(onNext: NextFn<firestore.QuerySnapshot>, onError?: ErrorFn, onCompletion?: CompleteFn): Unsubscribe;
    onSnapshot(options: firestore.SnapshotListenOptions, onNext: NextFn<firestore.QuerySnapshot>, onError?: ErrorFn, onCompletion?: CompleteFn): Unsubscribe;
    private onSnapshotInternal(options, observer);
    get(options?: firestore.GetOptions): Promise<firestore.QuerySnapshot>;
    private getViaSnapshotListener(resolve, reject, options?);
    private validateNewFilter(filter);
    private validateNewOrderBy(orderBy);
    private validateOrderByAndInequalityMatch(inequality, orderBy);
}
export declare class QuerySnapshot implements firestore.QuerySnapshot {
    private _firestore;
    private _originalQuery;
    private _snapshot;
    private _cachedChanges;
    private _cachedChangesIncludeMetadataChanges;
    readonly metadata: firestore.SnapshotMetadata;
    constructor(_firestore: Firestore, _originalQuery: InternalQuery, _snapshot: ViewSnapshot);
    readonly docs: firestore.QueryDocumentSnapshot[];
    readonly empty: boolean;
    readonly size: number;
    forEach(callback: (result: firestore.QueryDocumentSnapshot) => void, thisArg?: AnyJs): void;
    readonly query: firestore.Query;
    docChanges(options?: firestore.SnapshotListenOptions): firestore.DocumentChange[];
    /** Check the equality. The call can be very expensive. */
    isEqual(other: firestore.QuerySnapshot): boolean;
    private convertToDocumentImpl(doc);
}
export declare class CollectionReference extends Query implements firestore.CollectionReference {
    constructor(path: ResourcePath, firestore: Firestore);
    readonly id: string;
    readonly parent: firestore.DocumentReference | null;
    readonly path: string;
    doc(pathString?: string): firestore.DocumentReference;
    add(value: firestore.DocumentData): Promise<firestore.DocumentReference>;
}
/**
 * Calculates the array of firestore.DocumentChange's for a given ViewSnapshot.
 *
 * Exported for testing.
 */
export declare function changesFromSnapshot(firestore: Firestore, includeMetadataChanges: boolean, snapshot: ViewSnapshot): firestore.DocumentChange[];
export declare const PublicFirestore: typeof Firestore;
export declare const PublicTransaction: typeof Transaction;
export declare const PublicWriteBatch: typeof WriteBatch;
export declare const PublicDocumentReference: typeof DocumentReference;
export declare const PublicDocumentSnapshot: typeof DocumentSnapshot;
export declare const PublicQueryDocumentSnapshot: typeof QueryDocumentSnapshot;
export declare const PublicQuery: typeof Query;
export declare const PublicQuerySnapshot: typeof QuerySnapshot;
export declare const PublicCollectionReference: typeof CollectionReference;
