/** @packageDocumentation
 * @module iModels
 */
import { BeEvent, DbConflictResolution, DbResult, Id64String, IModelStatus } from "@itwin/core-bentley";
import { EntityIdAndClassIdIterable, ModelGeometryChangesProps, ModelIdAndGeometryGuid } from "@itwin/core-common";
import { BriefcaseDb, StandaloneDb } from "./IModelDb";
import { RelationshipProps } from "./Relationship";
import { DbRebaseChangesetConflictArgs, RebaseChangesetConflictArgs, TxnArgs } from "./internal/ChangesetConflictArgs";
/** A string that identifies a Txn.
 * @public @preview
 */
export type TxnIdString = string;
/** An error generated during dependency validation.
 * @see [[TxnManager.validationErrors]].
 * @public @preview
 */
export interface ValidationError {
    /** If true, txn is aborted. */
    fatal: boolean;
    /** The type of error. */
    errorType: string;
    /** Optional description of what went wrong. */
    message?: string;
}
/** Describes a set of [[Element]]s or [[Model]]s that changed as part of a transaction.
 * @see [[TxnManager.onElementsChanged]] and [[TxnManager.onModelsChanged]].
 * @public @preview
 */
export interface TxnChangedEntities {
    /** The entities that were inserted by the transaction. */
    readonly inserts: EntityIdAndClassIdIterable;
    /** The entities that were deleted by the transaction. */
    readonly deletes: EntityIdAndClassIdIterable;
    /** The entities that were modified by the transaction, including any [[Element]]s for which one of their [[ElementAspect]]s was changed. */
    readonly updates: EntityIdAndClassIdIterable;
}
/** Arguments supplied to [[TxnManager.queryLocalChanges]].
 * @beta
 */
export interface QueryLocalChangesArgs {
    /** If supplied and non-empty, restricts the results to include only EC instances belonging to the specified classes or subclasses thereof. */
    readonly includedClasses?: string[];
    /** If `true`, include changes that have not yet been saved. */
    readonly includeUnsavedChanges?: boolean;
}
/** Represents a change (insertion, deletion, or modification) to a single EC instance made in a local [[BriefcaseDb]].
 * @see [[TxnManager.queryLocalChanges]] to iterate all of the changed instances.
* @beta
*/
export interface ChangeInstanceKey {
    /** ECInstanceId of the instance. */
    id: Id64String;
    /** Fully-qualified class name of the instance. */
    classFullName: string;
    /** The type of change. */
    changeType: "inserted" | "updated" | "deleted";
}
/** Strictly for tests. @internal */
export declare function setMaxEntitiesPerEvent(max: number): number;
/**
 * @internal
 * Manages conflict resolution during a merge operation.
*/
export declare class ChangeMergeManager {
    private _iModel;
    private _conflictHandlers?;
    constructor(_iModel: BriefcaseDb | StandaloneDb);
    resume(): void;
    inProgress(): boolean;
    onConflict(args: RebaseChangesetConflictArgs): DbConflictResolution | undefined;
    addConflictHandler(args: {
        id: string;
        handler: (args: RebaseChangesetConflictArgs) => DbConflictResolution | undefined;
    }): void;
    removeConflictHandler(id: string): void;
}
/** Manages local changes to a [[BriefcaseDb]] or [[StandaloneDb]] via [Txns]($docs/learning/InteractiveEditing.md)
 * @public @preview
 */
export declare class TxnManager {
    private _iModel;
    /** @internal */
    private _isDisposed;
    /** @internal */
    get isDisposed(): boolean;
    /** @internal */
    readonly changeMergeManager: ChangeMergeManager;
    /** @internal */
    constructor(_iModel: BriefcaseDb | StandaloneDb);
    /** Array of errors from dependency propagation */
    readonly validationErrors: ValidationError[];
    private get _nativeDb();
    private _getElementClass;
    private _getRelationshipClass;
    /** If a -watch file exists for this iModel, update its timestamp so watching processes can be
     * notified that we've modified the briefcase.
     * @internal Used by IModelDb on push/pull.
     */
    touchWatchFile(): void;
    /** @internal */
    protected _onBeforeOutputsHandled(elClassName: string, elId: Id64String): void;
    /** @internal */
    protected _onAllInputsHandled(elClassName: string, elId: Id64String): void;
    /** @internal */
    protected _onRootChanged(props: RelationshipProps): void;
    /** @internal */
    protected _onDeletedDependency(props: RelationshipProps): void;
    /** @internal */
    protected _onBeginValidate(): void;
    /** called from native code after validation of a Txn, either from saveChanges or apply changeset.
     * @internal
     */
    protected _onEndValidate(): void;
    /** @internal */
    protected _onGeometryChanged(modelProps: ModelGeometryChangesProps[]): void;
    /** @internal */
    protected _onGeometryGuidsChanged(changes: ModelIdAndGeometryGuid[]): void;
    /** @internal */
    protected _onCommit(): void;
    /** @internal */
    protected _onCommitted(): void;
    /** @internal */
    protected _onReplayExternalTxns(): void;
    /** @internal */
    protected _onReplayedExternalTxns(): void;
    /** @internal */
    protected _onChangesApplied(): void;
    /** @internal */
    protected _onBeforeUndoRedo(isUndo: boolean): void;
    /** @internal */
    protected _onAfterUndoRedo(isUndo: boolean): void;
    private _onRebaseTxnBegin;
    private _onRebaseTxnEnd;
    private _onRebaseLocalTxnConflict;
    /** Dependency handlers may call method this to report a validation error.
     * @param error The error. If error.fatal === true, the transaction will cancel rather than commit.
     */
    reportError(error: ValidationError): void;
    /** Determine whether any fatal validation errors have occurred during dependency propagation.  */
    get hasFatalError(): boolean;
    /** @internal */
    readonly onEndValidation: BeEvent<() => void>;
    /** Called after validation completes from [[IModelDb.saveChanges]].
     * The argument to the event holds the list of elements that were inserted, updated, and deleted.
     * @note If there are many changed elements in a single Txn, the notifications are sent in batches so this event *may be called multiple times* per Txn.
     */
    readonly onElementsChanged: BeEvent<(changes: TxnChangedEntities) => void>;
    /** Called after validation completes from [[IModelDb.saveChanges]].
     * The argument to the event holds the list of models that were inserted, updated, and deleted.
     * @note If there are many changed models in a single Txn, the notifications are sent in batches so this event *may be called multiple times* per Txn.
     */
    readonly onModelsChanged: BeEvent<(changes: TxnChangedEntities) => void>;
    /** Event raised after the geometry within one or more [[GeometricModel]]s is modified by applying a changeset or validation of a transaction.
     * A model's geometry can change as a result of:
     *  - Insertion or deletion of a geometric element within the model; or
     *  - Modification of an existing element's geometric properties; or
     *  - An explicit request to flag it as changed via [[IModelDb.Models.updateModel]].
     */
    readonly onModelGeometryChanged: BeEvent<(changes: ReadonlyArray<ModelIdAndGeometryGuid>) => void>;
    readonly onGeometryChanged: BeEvent<(models: ModelGeometryChangesProps[]) => void>;
    /** Event raised before a commit operation is performed. Initiated by a call to [[IModelDb.saveChanges]], unless there are no changes to save. */
    readonly onCommit: BeEvent<() => void>;
    /** Event raised after a commit operation has been performed. Initiated by a call to [[IModelDb.saveChanges]], even if there were no changes to save. */
    readonly onCommitted: BeEvent<() => void>;
    /** Event raised after a ChangeSet has been applied to this briefcase */
    readonly onChangesApplied: BeEvent<() => void>;
    /** Event raised before an undo/redo operation is performed. */
    readonly onBeforeUndoRedo: BeEvent<(isUndo: boolean) => void>;
    /** Event raised after an undo/redo operation has been performed.
     * @param _action The action that was performed.
     */
    readonly onAfterUndoRedo: BeEvent<(isUndo: boolean) => void>;
    /** Event raised for a read-only briefcase that was opened with the `watchForChanges` flag enabled when changes made by another connection are applied to the briefcase.
     * @see [[onReplayedExternalTxns]] for the event raised after all such changes have been applied.
     */
    readonly onReplayExternalTxns: BeEvent<() => void>;
    /** Event raised for a read-only briefcase that was opened with the `watchForChanges` flag enabled when changes made by another connection are applied to the briefcase.
     * @see [[onReplayExternalTxns]] for the event raised before the changes are applied.
     */
    readonly onReplayedExternalTxns: BeEvent<() => void>;
    /** @internal */
    readonly onRebaseTxnBegin: BeEvent<(txn: TxnArgs) => void>;
    /** @internal */
    readonly onRebaseTxnEnd: BeEvent<(txn: TxnArgs) => void>;
    /**
     * if handler is set and it does not return undefiend then default handler will not be called
     * @internal
     * */
    appCustomConflictHandler?: (args: DbRebaseChangesetConflictArgs) => DbConflictResolution | undefined;
    /**
     * Restart the current TxnManager session. This causes all Txns in the current session to no longer be undoable (as if the file was closed
     * and reopened.)
     * @note This can be quite disconcerting to the user expecting to be able to undo previously made changes. It should only be used
     * under extreme circumstances where damage to the file or session could happen if the currently committed are reversed. Use sparingly and with care.
     * Probably a good idea to alert the user it happened.
     */
    restartSession(): void;
    /** Determine whether current txn is propagating indirect changes or not. */
    get isIndirectChanges(): boolean;
    /** Determine if there are currently any reversible (undoable) changes from this editing session. */
    get isUndoPossible(): boolean;
    /** Determine if there are currently any reinstatable (redoable) changes */
    get isRedoPossible(): boolean;
    /** Get the description of the operation that would be reversed by calling reverseTxns(1).
     * This is useful for showing the operation that would be undone, for example in a menu.
     */
    getUndoString(): string;
    /** Get a description of the operation that would be reinstated by calling reinstateTxn.
     * This is useful for showing the operation that would be redone, in a pull-down menu for example.
     */
    getRedoString(): string;
    /** Begin a new multi-Txn operation. This can be used to cause a series of Txns that would normally
     * be considered separate actions for undo to be grouped into a single undoable operation. This means that when reverseTxns(1) is called,
     * the entire group of changes are undone together. Multi-Txn operations can be nested and until the outermost operation is closed
     * all changes constitute a single operation.
     * @note This method must always be paired with a call to endMultiTxnAction.
     */
    beginMultiTxnOperation(): DbResult;
    /** End a multi-Txn operation */
    endMultiTxnOperation(): DbResult;
    /** Return the depth of the multi-Txn stack. Generally for diagnostic use only. */
    getMultiTxnOperationDepth(): number;
    /** Reverse (undo) the most recent operation(s) to this IModelDb.
     * @param numOperations the number of operations to reverse. If this is greater than 1, the entire set of operations will
     *  be reinstated together when/if ReinstateTxn is called.
     * @note If there are any outstanding uncommitted changes, they are reversed.
     * @note The term "operation" is used rather than Txn, since multiple Txns can be grouped together via [[beginMultiTxnOperation]]. So,
     * even if numOperations is 1, multiple Txns may be reversed if they were grouped together when they were made.
     * @note If numOperations is too large only the operations are reversible are reversed.
     */
    reverseTxns(numOperations: number): IModelStatus;
    /** Reverse the most recent operation. */
    reverseSingleTxn(): IModelStatus;
    /** Reverse all changes back to the beginning of the session. */
    reverseAll(): IModelStatus;
    /** Reverse all changes back to a previously saved TxnId.
     * @param txnId a TxnId obtained from a previous call to GetCurrentTxnId.
     * @returns Success if the transactions were reversed, error status otherwise.
     * @see  [[getCurrentTxnId]] [[cancelTo]]
     */
    reverseTo(txnId: TxnIdString): IModelStatus;
    /** Reverse and then cancel (make non-reinstatable) all changes back to a previous TxnId.
     * @param txnId a TxnId obtained from a previous call to [[getCurrentTxnId]]
     * @returns Success if the transactions were reversed and cleared, error status otherwise.
     */
    cancelTo(txnId: TxnIdString): IModelStatus;
    /** Reinstate the most recently reversed transaction. Since at any time multiple transactions can be reversed, it
     * may take multiple calls to this method to reinstate all reversed operations.
     * @returns Success if a reversed transaction was reinstated, error status otherwise.
     * @note If there are any outstanding uncommitted changes, they are canceled before the Txn is reinstated.
     */
    reinstateTxn(): IModelStatus;
    /** Get the Id of the first transaction, if any.
     */
    queryFirstTxnId(): TxnIdString;
    /** Get the successor of the specified TxnId */
    queryNextTxnId(txnId: TxnIdString): TxnIdString;
    /** Get the predecessor of the specified TxnId */
    queryPreviousTxnId(txnId: TxnIdString): TxnIdString;
    /** Get the Id of the current (tip) transaction.  */
    getCurrentTxnId(): TxnIdString;
    /** Get the description that was supplied when the specified transaction was saved. */
    getTxnDescription(txnId: TxnIdString): string;
    /** Test if a TxnId is valid */
    isTxnIdValid(txnId: TxnIdString): boolean;
    /** Query if there are any pending Txns in this IModelDb that are waiting to be pushed.
     * @see [[IModelDb.pushChanges]]
     */
    get hasPendingTxns(): boolean;
    /**
     * Query if there are any changes in memory that have yet to be saved to the IModelDb.
     * @see [[IModelDb.saveChanges]]
     */
    get hasUnsavedChanges(): boolean;
    /**
     * Query if there are changes in memory that have not been saved to the iModelDb or if there are Txns that are waiting to be pushed.
     * @see [[IModelDb.saveChanges]]
     * @see [[IModelDb.pushChanges]]
     */
    get hasLocalChanges(): boolean;
    /** Destroy the record of all local changes that have yet to be saved and/or pushed.
     * This permanently eradicates your changes - use with caution!
     * Typically, callers will want to subsequently use [[LockControl.releaseAllLocks]].
     * After calling this function, [[hasLocalChanges]], [[hasPendingTxns]], and [[hasUnsavedChanges]] will all be `false`.
     */
    deleteAllTxns(): void;
    /** Obtain a list of the EC instances that have been changed locally by the [[BriefcaseDb]] associated with this `TxnManager` and have not yet been pushed to the iModel.
     * @beta
    */
    queryLocalChanges(args?: QueryLocalChangesArgs): Iterable<ChangeInstanceKey>;
    /** Query the number of bytes of memory currently allocated by SQLite to keep track of
     * changes to the iModel, for debugging/diagnostic purposes, as reported by [sqlite3session_memory_used](https://www.sqlite.org/session/sqlite3session_memory_used.html).
     */
    getChangeTrackingMemoryUsed(): number;
}
//# sourceMappingURL=TxnManager.d.ts.map