/**
 * GitDocumentDB
 * Copyright (c) Hidekazu Kubota
 *
 * This source code is licensed under the Mozilla Public License Version 2.0
 * found in the LICENSE file in the root directory of this source tree.
 */
import { RemoteOptions, SyncCallback, SyncChangeCallback, SyncCombineDatabaseCallback, SyncCompleteCallback, SyncErrorCallback, SyncEvent, SyncLocalChangeCallback, SyncPauseCallback, SyncRemoteChangeCallback, SyncResult, SyncResultCancel, SyncResultNop, SyncResultPush, SyncResumeCallback, SyncStartCallback } from '../types';
import { SyncInterface } from '../types_sync';
import { GitDDBInterface } from '../types_gitddb';
import { RemoteRepository } from './remote_repository';
import { JsonDiff } from './json_diff';
import { JsonPatchOT } from './json_patch_ot';
/**
 * encodeToGitRemoteName
 *
 * @remarks
 * The first default name of Git remote is "origin".
 *
 * GitDocumentDB adds an alias of "origin",
 * whose name is generated automatically by this function.
 * The second and subsequent remotes are also named in the same way.
 *
 * A remote name consists of [remote address]_[hash].
 * Periods are replaced with underscores.
 * e.g.) github_com_a0b1c23
 * It is human-readable.
 *
 * [remote address] is [hostname + domain name] or [ip address].
 * [hash] is calculated from remoteURL.
 *
 * [hash] is the first seven characters of SHA-1 so that it may collide.
 * Capitalize one of the remote addresses when hashes collide
 * because a hostname and a domain name are not case sensitive.
 *
 * @throws {@link RemoteErr.InvalidURLFormatError}
 *
 * @public
 */
export declare function encodeToGitRemoteName(remoteURL: string): string;
/**
 * Implementation of GitDocumentDB#sync(options, get_sync_result)
 *
 * @throws {@link Err.DatabaseClosingError}
 * @throws {@link Err.RepositoryNotOpenError}
 *
 * @throws # Errors from constructor of {@link Sync} class.
 * @throws # Errors from {@link Sync.init}
 *
 * @internal
 */
export declare function syncAndGetResultImpl(this: GitDDBInterface, options: RemoteOptions): Promise<[Sync, SyncResult]>;
/**
 * Implementation of GitDocumentDB#sync(options)
 *
 * @throws {@link Err.DatabaseClosingError}
 * @throws {@link Err.RepositoryNotOpenError}
 *
 * @throws # Errors from constructor of {@link Sync} class.
 * @throws # Errors from {@link Sync.init}
 *
 * @internal
 */
export declare function syncImpl(this: GitDDBInterface, options: RemoteOptions): Promise<Sync>;
/**
 * Synchronizer class
 *
 * @public
 */
export declare class Sync implements SyncInterface {
    /**********************************************
     * Private properties
     ***********************************************/
    private _gitDDB;
    private _syncTimer;
    private _retrySyncCounter;
    private _isClosed;
    /***********************************************
     * Public properties (readonly)
     ***********************************************/
    /**
     * remoteURL
     *
     * @readonly
     * @public
     */
    get remoteURL(): string;
    /**
     * Remote Engine
     */
    private _engine;
    get engine(): string;
    private _remoteRepository;
    /**
     * Remote repository
     *
     * @readonly
     * @public
     */
    get remoteRepository(): RemoteRepository;
    private _options;
    /**
     * Get a clone of remote options
     *
     * @readonly
     * @public
     */
    get options(): Required<RemoteOptions>;
    private _remoteName;
    /**
     * remoteName
     *
     * @readonly
     * @public
     */
    get remoteName(): string;
    /***********************************************
     * Public properties
     ***********************************************/
    /**
     * runBeforeLiveSync
     *
     * This function is executed just before each automated(live) synchronization event is queued.
     * Set undefined to stop it.
     */
    runBeforeLiveSync: (() => void) | undefined;
    /**
     * SyncEvent handlers
     *
     * @internal
     */
    eventHandlers: {
        change: {
            collectionPath: string;
            func: SyncChangeCallback;
        }[];
        localChange: {
            collectionPath: string;
            func: SyncLocalChangeCallback;
        }[];
        remoteChange: {
            collectionPath: string;
            func: SyncRemoteChangeCallback;
        }[];
        combine: {
            collectionPath: string;
            func: SyncCombineDatabaseCallback;
        }[];
        pause: {
            collectionPath: string;
            func: SyncPauseCallback;
        }[];
        resume: {
            collectionPath: string;
            func: SyncResumeCallback;
        }[];
        start: {
            collectionPath: string;
            func: SyncStartCallback;
        }[];
        complete: {
            collectionPath: string;
            func: SyncCompleteCallback;
        }[];
        error: {
            collectionPath: string;
            func: SyncErrorCallback;
        }[];
    };
    /**
     * JsonDiff
     *
     * @public
     */
    jsonDiff: JsonDiff;
    /**
     * JsonPatch
     *
     * @public
     */
    jsonPatch: JsonPatchOT;
    /**
     * constructor
     *
     * @throws {@link Err.UndefinedRemoteURLError}
     * @throws {@link Err.IntervalTooSmallError}
     * @throws {@link Err.SyncIntervalLessThanOrEqualToRetryIntervalError}
     *
     * @throws # Errors from encodeToGitRemoteName
     * @throws - {@link RemoteErr.InvalidURLFormatError}
     *
     * @public
     */
    constructor(gitDDB: GitDDBInterface, options?: RemoteOptions);
    /***********************************************
     * Public methods
     ***********************************************/
    /**
     * Initialize remote connection
     *
     * @remarks
     * Call init() once just after creating an instance.
     *
     * @throws {@link Err.CannotCreateRemoteRepositoryError}
     *
     * @throws # Errors from RemoteEngine[engineName].checkFetch
     * @throws - {@link RemoteErr.InvalidGitRemoteError}
     * @throws - {@link RemoteErr.InvalidURLFormatError}
     * @throws - {@link RemoteErr.NetworkError}
     * @throws - {@link RemoteErr.HTTPError401AuthorizationRequired}
     * @throws - {@link RemoteErr.HTTPError404NotFound}
     * @throws - {@link RemoteErr.CannotConnectError}
     * @throws - {@link RemoteErr.InvalidURLFormatError}
     * @throws - {@link RemoteErr.InvalidRepositoryURLError}
     * @throws - {@link RemoteErr.InvalidSSHKeyPathError}
     * @throws - {@link RemoteErr.InvalidAuthenticationTypeError}
     *
     * @throws Errors from {@link Sync.trySync}
     * @throws Errors from {@link Sync.tryPush}
     *
     * @public
     */
    init(): Promise<SyncResult>;
    /**
     * Pause synchronization
     *
     * @public
     */
    pause(): boolean;
    /**
     * Resume synchronization
     *
     * @remarks
     * Give new settings if needed.
     *
     * @throws {@link Err.IntervalTooSmallError}
     *
     * @public
     */
    resume(options?: {
        interval?: number;
        retry?: number;
    }): boolean;
    /**
     * Stop and clear remote connection
     *
     * @public
     */
    close(): void;
    /**
     * Try to push
     *
     * @throws {@link Err.PushNotAllowedError}
     *
     * @throws # Errors from push
     * @throws - {@link RemoteErr.InvalidGitRemoteError}
     * @throws - {@link RemoteErr.UnfetchedCommitExistsError}
     * @throws - {@link RemoteErr.InvalidURLFormatError}
     * @throws - {@link RemoteErr.NetworkError}
     * @throws - {@link RemoteErr.HTTPError401AuthorizationRequired}
     * @throws - {@link RemoteErr.HTTPError404NotFound}
     * @throws - {@link RemoteErr.HTTPError403Forbidden}
     * @throws - {@link RemoteErr.CannotConnectError}
     * @throws - {@link RemoteErr.UnfetchedCommitExistsError}
     * @throws - {@link RemoteErr.CannotConnectError}
     * @throws - {@link RemoteErr.InvalidURLFormatError}
     * @throws - {@link RemoteErr.InvalidRepositoryURLError}
     * @throws - {@link RemoteErr.InvalidSSHKeyPathError}
     * @throws - {@link RemoteErr.InvalidAuthenticationTypeError}
     *
     * @throws # Errors from getChanges
     * @throws - {@link Err.InvalidJsonObjectError}
     *
     * @public
     */
    tryPush(): Promise<SyncResultPush | SyncResultCancel | SyncResultNop>;
    /**
     * tryPushImpl
     *
     * @internal
     */
    tryPushImpl(calledAsPeriodicTask: boolean): Promise<SyncResultPush | SyncResultCancel | SyncResultNop>;
    /**
     * Try to sync with retries
     *
     * @throws {@link Err.PushNotAllowedError}
     * @throws {@link Err.CombineDatabaseError}
     *
     * @throws # Errors from syncWorker
     * @throws - {@link Err.NoMergeBaseFoundError}
     * @throws - {@link Err.ThreeWayMergeError}
     * @throws - {@link Err.CannotDeleteDataError}
     *
     * @throws # Errors from fetch, pushWorker
     * @throws - {@link RemoteErr.InvalidGitRemoteError}
     * @throws - {@link RemoteErr.InvalidURLFormatError}
     * @throws - {@link RemoteErr.NetworkError}
     * @throws - {@link RemoteErr.HTTPError401AuthorizationRequired}
     * @throws - {@link RemoteErr.HTTPError404NotFound}
     * @throws - {@link RemoteErr.CannotConnectError}
     * @throws - {@link RemoteErr.InvalidURLFormatError}
     * @throws - {@link RemoteErr.InvalidRepositoryURLError}
     * @throws - {@link RemoteErr.InvalidSSHKeyPathError}
     * @throws - {@link RemoteErr.InvalidAuthenticationTypeError}
     *
     * @throws # Errors from pushWorker
     * @throws - {@link RemoteErr.HTTPError403Forbidden}
     * @throws - {@link RemoteErr.UnfetchedCommitExistsError}
     *
     * @throws # Errors from merge
     * @throws - {@link Err.InvalidConflictStateError}
     * @throws - {@link Err.CannotDeleteDataError}
     * @throws - {@link Err.InvalidDocTypeError}
     * @throws - {@link Err.InvalidConflictResolutionStrategyError}
     * @throws - {@link Err.CannotCreateDirectoryError}
     * @throws - {@link Err.InvalidJsonObjectError}
     *
     * @throws # Errors from getChanges
     * @throws - {@link Err.InvalidJsonObjectError}
     *
     * @public
     */
    trySync(): Promise<SyncResult>;
    /**
     * trySyncImpl
     *
     * @internal
     */
    trySyncImpl(calledAsPeriodicTask: boolean): Promise<SyncResult>;
    /**
     * Enqueue sync task to TaskQueue
     *
     * @public
     */
    enqueueSyncTask(calledAsPeriodicTask: boolean): Promise<SyncResult>;
    /**
     * Return current retry count (incremental)
     *
     * @public
     */
    currentRetries(): number;
    /**
     * Add SyncEvent handler
     *
     * @eventProperty
     * @public
     */
    on(event: SyncEvent, callback: SyncCallback, collectionPath?: string): this;
    /**
     * Remove SyncEvent handler
     *
     * @eventProperty
     * @public
     */
    off(event: SyncEvent, callback: SyncCallback): this;
}
//# sourceMappingURL=sync.d.ts.map