import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
import { Error as ErrorEvent } from "@matrix-org/analytics-events/types/typescript/Error";
import { DecryptionFailureCode } from "matrix-js-sdk/src/crypto-api";
export declare class DecryptionFailure {
    readonly failedEventId: string;
    readonly errorCode: DecryptionFailureCode;
    /**
     * The time that we failed to decrypt the event.  If we failed to decrypt
     * multiple times, this will be the time of the first failure.
     */
    readonly ts: number;
    /**
     * Is the sender on a different server from us?
     */
    readonly isFederated: boolean | undefined;
    /**
     * Was the failed event ever visible to the user?
     */
    wasVisibleToUser: boolean;
    /**
     * Has the user verified their own cross-signing identity, as of the most
     * recent decryption attempt for this event?
     */
    userTrustsOwnIdentity: boolean | undefined;
    /**
     * The time between our initial failure to decrypt and our successful
     * decryption (if we managed to decrypt).
     */
    timeToDecryptMillis?: number;
    constructor(failedEventId: string, errorCode: DecryptionFailureCode, 
    /**
     * The time that we failed to decrypt the event.  If we failed to decrypt
     * multiple times, this will be the time of the first failure.
     */
    ts: number, 
    /**
     * Is the sender on a different server from us?
     */
    isFederated: boolean | undefined, 
    /**
     * Was the failed event ever visible to the user?
     */
    wasVisibleToUser: boolean, 
    /**
     * Has the user verified their own cross-signing identity, as of the most
     * recent decryption attempt for this event?
     */
    userTrustsOwnIdentity: boolean | undefined);
}
type ErrorCode = ErrorEvent["name"];
/** Properties associated with decryption errors, for classifying the error. */
export type ErrorProperties = Omit<ErrorEvent, "eventName" | "domain" | "name" | "context">;
export type ErrCodeMapFn = (errcode: DecryptionFailureCode) => ErrorCode;
export declare class DecryptionFailureTracker {
    private readonly fn;
    private readonly errorCodeMapFn;
    private readonly checkReportedEvents;
    private static internalInstance;
    /** Map of event IDs to `DecryptionFailure` items.
     *
     * Every `CHECK_INTERVAL_MS`, this map is checked for failures that happened >
     * `MAXIMUM_LATE_DECRYPTION_PERIOD` ago (considered undecryptable), or
     * decryptions that took > `GRACE_PERIOD_MS` (considered late decryptions).
     *
     * Any such events are then reported via the `TrackingFn`.
     */
    failures: Map<string, DecryptionFailure>;
    /** Set of event IDs that have been visible to the user.
     *
     * This will only contain events that are not already in `reportedEvents`.
     */
    visibleEvents: Set<string>;
    /** Bloom filter tracking event IDs of failures that were reported previously */
    private reportedEvents;
    /** Set to an interval ID when `start` is called */
    checkInterval: number | null;
    trackInterval: number | null;
    /** Call `checkFailures` every `CHECK_INTERVAL_MS`. */
    static CHECK_INTERVAL_MS: number;
    /** If the event is successfully decrypted in less than 4s, we don't report. */
    static GRACE_PERIOD_MS: number;
    /** Maximum time for an event to be decrypted to be considered a late
     * decryption.  If it takes longer, we consider it undecryptable. */
    static MAXIMUM_LATE_DECRYPTION_PERIOD: number;
    /** Properties that will be added to all reported events (mainly reporting
     * information about the Matrix client). */
    private baseProperties?;
    /** The user's domain (homeserver name). */
    private userDomain?;
    /** Whether the user has verified their own cross-signing keys. */
    private userTrustsOwnIdentity;
    /** Whether we are currently checking our own verification status. */
    private checkingVerificationStatus;
    /** Whether we should retry checking our own verification status after we're
     * done our current check. i.e. we got notified that our keys changed while
     * we were already checking, so the result could be out of date. */
    private retryVerificationStatus;
    /**
     * Create a new DecryptionFailureTracker.
     *
     * Call `start(client)` to start the tracker.  The tracker will listen for
     * decryption events on the client and track decryption failures, and will
     * automatically stop tracking when the client logs out.
     *
     * @param {function} fn The tracking function, which will be called when failures
     * are tracked. The function should have a signature `(trackedErrorCode, rawError, properties) => {...}`,
     * where `errorCode` matches the output of `errorCodeMapFn`, `rawError` is the original
     * error (that is, the input to `errorCodeMapFn`), and `properties` is a map of the
     * error properties for classifying the error.
     *
     * @param {function} errorCodeMapFn The function used to map decryption failure reason  codes to the
     * `trackedErrorCode`.
     *
     * @param {boolean} checkReportedEvents Check if we have already reported an event.
     * Defaults to `true`. This is only used for tests, to avoid possible false positives from
     * the Bloom filter. This should be set to `false` for all tests except for those
     * that specifically test the `reportedEvents` functionality.
     */
    private constructor();
    static get instance(): DecryptionFailureTracker;
    private loadReportedEvents;
    private saveReportedEvents;
    /** Callback for when an event is decrypted.
     *
     * This function is called by our `MatrixEventEvent.Decrypted` event
     * handler after a decryption attempt on an event, whether the decryption
     * is successful or not.
     *
     * @param e the event that was decrypted
     *
     * @param nowTs the current timestamp
     */
    private eventDecrypted;
    addVisibleEvent(e: MatrixEvent): void;
    removeDecryptionFailuresForEvent(e: MatrixEvent, nowTs: number): void;
    private handleKeysChanged;
    /**
     * Start checking for and tracking failures.
     */
    start(client: MatrixClient): Promise<void>;
    private calculateClientProperties;
    private registerHandlers;
    /**
     * Clear state and stop checking for and tracking failures.
     */
    private stop;
    /**
     * Mark failures as undecryptable or late. Only mark one failure per event ID.
     *
     * @param {number} nowTs the timestamp that represents the time now.
     */
    checkFailures(nowTs: number): void;
    /**
     * If there are failures that should be tracked, call the given trackDecryptionFailure
     * function with the failures that should be tracked.
     */
    private reportFailure;
}
export {};
