import { TracedEventEmitter } from "@superblocksteam/shared";
import { type ErrorEventMap } from "../errors/error-handler.js";
import type { AutoConnectingRpcClient } from "../server-rpc/index.js";
import type { Logger } from "../util/logger.js";
import type { Tracer } from "@opentelemetry/api";
import type { LockInfo } from "@superblocksteam/shared";
export declare enum LockServiceStatus {
    /** The lock service is not currently active */
    IDLE = "IDLE",
    /** The lock service is acquiring a lock */
    ACQUIRING = "ACQUIRING",
    /** The lock service has acquired a lock */
    LOCKED = "LOCKED",
    /** The lock service is releasing a lock */
    RELEASING = "RELEASING",
    /** The lock service is waiting for a lock to be released */
    FAILED_TO_ACQUIRE_LOCK = "FAILED_TO_ACQUIRE_LOCK",
    /** The lock is invalid */
    LOCK_INVALID = "LOCK_INVALID",
    /** The lock is released */
    LOCK_RELEASED = "LOCK_RELEASED"
}
export declare enum LockType {
    LOCAL = "local",
    CSB = "csb"
}
/** Configuration for the LockService passed to the constructor */
export interface LockServiceConfig {
    superblocksBaseUrl: string;
    applicationId: string;
    branchName: string;
    lockType: LockType;
    heartbeatIntervalMs?: number;
    inactivityThresholdMs: number;
    lockBufferMs?: number;
    startupConnectionTimeoutMs?: number;
    rpcClient: AutoConnectingRpcClient;
    tracer: Tracer;
    logger: Logger;
}
interface EventMap extends ErrorEventMap {
    /** Emitted when the lock service status changes */
    statusChange: [status: LockServiceStatus, lockInfo?: LockInfo];
    /** Emitted when the lock is acquired */
    lockAcquired: [lockId: string];
    /** Emitted when the lock is released */
    lockReleased: [];
    /** Emitted when the lock heartbeat is received */
    lockHeartbeat: [lockId: string];
    /** Emitted when the lock is released by the server */
    closedByServer: [
        {
            initiatedByEmail?: string;
            switchingTo?: "local" | "cloud" | "none";
        }
    ];
}
export declare class LockService extends TracedEventEmitter<EventMap> {
    private readonly applicationId;
    private readonly branchName;
    private readonly lockType;
    private readonly heartbeatIntervalMs;
    private syncCallback;
    private waitForGenerationCompleteCallback;
    private _status;
    private _lockId;
    private _heartbeatTimeout;
    private _inactivityTimeout;
    private _bufferPeriodTimeout;
    private _isRestarting;
    private _tracer;
    private _logger;
    private _rpcClient;
    private _inactivityThresholdMs;
    private _lockBufferMs;
    private _startupConnectionTimeoutMs;
    private _startupConnectionTimeout;
    private _startupConnectionTimeoutStartedAt;
    private _startupConnectionTimeoutExpired;
    private _activityTracker;
    constructor(config: LockServiceConfig);
    private getLogger;
    setSyncCallback(callback: () => Promise<void>): void;
    setWaitForGenerationCompleteCallback(callback: () => Promise<void>): void;
    get status(): LockServiceStatus;
    private set status(value);
    get isLocked(): boolean;
    get lockId(): string | undefined;
    get connectedUsers(): string[];
    get isRestarting(): boolean;
    get wasRecentlyActive(): boolean;
    get timeSinceLastActivity(): number | null;
    /**
     * Check if the lock service is in a state where it can reacquire a lock.
     * This happens when the lock was released but dev server is still alive.
     */
    get canReacquireLock(): boolean;
    /**
     * Acquire a lock on the specified application and branch
     */
    acquireLock(): Promise<void>;
    /**
     * Release the currently held lock
     */
    releaseLock(): Promise<boolean>;
    private grabLockImpl;
    /**
     * Inspect lock information for the current application and branch
     */
    inspectLock(): Promise<LockInfo>;
    /**
     * Force takeover of the lock from another user (only allowed when user is inactive)
     */
    forceTakeover(): Promise<void>;
    checkAndUpdateLockIfPossible(): Promise<boolean>;
    /**
     * Cleanup method to be called when the class is destroyed
     * This ensures the lock is released
     */
    shutdown({ serverInitiated, switchingTo, initiatedByEmail, }: {
        serverInitiated?: boolean;
        switchingTo?: "local" | "cloud" | "none";
        initiatedByEmail?: string;
    }): Promise<void>;
    /**
     * Shutdown the lock service and exit the dev server
     */
    shutdownAndExit(): Promise<void>;
    /**
     * Add a connected user to the activity tracker.
     */
    addConnectedPeerIdToUser(userId: string, peerId: string): void;
    /**
     * Remove a connected user from the activity tracker.
     */
    removeConnectedPeerIdFromUser(userId: string, peerId: string): void;
    private scheduleNextHeartbeat;
    private sendHeartbeat;
    /**
     * Stop the heartbeat
     */
    private stopHeartbeat;
    private clearStartupConnectionTimeout;
    private startStartupConnectionTimeoutIfNeeded;
    private evaluateStartupConnectionTimeoutIfNeeded;
    /**
     * Evaluate if the lock should be released (user disconnected) or marked as ready for takeover (user inactive but connected)
     */
    evaluateLockState(): Promise<void>;
    /**
     * Restart the inactivity timer when user activity is detected.
     * This timer tracks if the user goes inactive (no pings for N minutes).
     */
    restartInactivityTimer(): Promise<void>;
    /**
     * Mark the user's activity from UI ping
     */
    markActivity(isUserActive: boolean): void;
    /** when the dev server is restarting, we will use the 5-minute shutdown timer instead of the instant one */
    setIsRestarting(): Promise<void>;
}
export {};
//# sourceMappingURL=index.d.ts.map