/**
 * AccountManager — keeps one SimpleIMAPService + SMTPService per account
 * alive concurrently, supports hot-swapping the "active" account without
 * a server restart, and lets the tool dispatcher route individual calls
 * to a specific account via its `account_id` argument.
 *
 * Design notes
 *   - One ImapFlow connection per account. imapflow's documented pattern
 *     is "N separate clients" (no built-in pool); IDLE auto-runs per
 *     client. Memory is bounded because mailpouch is single-user and
 *     most users have ≤ 3 accounts.
 *   - Lazy connection: services are created per account at AccountManager
 *     construction, but the underlying IMAP socket only opens on first
 *     use. Same for the SMTP transporter (nodemailer is construct-cheap).
 *   - Hot-swap semantics: changing the active account rewires the module-
 *     level `imapService` / `smtpService` references via injected setters.
 *     Callers that were mid-flight keep their existing bindings — ALS or
 *     closure captures of the prior active services continue to work
 *     until the call completes.
 *   - Credential scope: each account's password/SMTP token stays scoped
 *     to its own service instances. Switching accounts never leaks
 *     creds across account boundaries.
 */
import { SMTPService } from "../services/smtp-service.js";
import { SimpleIMAPService } from "../services/simple-imap-service.js";
import type { AccountSpec } from "./types.js";
import { EventEmitter } from "events";
export interface AccountServices {
    imap: SimpleIMAPService;
    smtp: SMTPService;
    spec: AccountSpec;
}
export declare class AccountManager extends EventEmitter {
    private readonly perAccount;
    private _activeAccountId;
    constructor();
    /**
     * Rebuild the account map from the persisted registry. Called at
     * construction and after any setActiveAccount / registry mutation.
     * Preserves in-flight service instances for accounts that still exist;
     * tears down instances for accounts that were deleted; constructs new
     * instances for accounts that were added.
     *
     * Synchronous variant that reads the on-disk state WITHOUT pulling
     * plaintext creds from the keychain — intended for the construction
     * path where we can't block on an async keychain call. Use
     * `rebuildFromRegistryAsync()` (below) when you need the creds
     * populated — main() calls the async version right after boot.
     */
    rebuildFromRegistry(): void;
    /**
     * Async rebuild that fills credentials from the OS keychain. Called
     * by main() right after boot and after any Accounts-tab mutation
     * that lands via the settings-UI server — ensures the in-memory
     * services have the passwords the user persisted, even though the
     * on-disk config blanks them.
     */
    rebuildFromRegistryAsync(): Promise<void>;
    /** The account currently wired into the module-level service references. */
    activeAccountId(): string;
    /** Services for whichever account is currently active. */
    getActive(): AccountServices;
    /** Services for a specific account (by id). Throws on unknown id. */
    getForAccount(accountId: string): AccountServices;
    /** Enumerate all accounts the manager knows about. */
    list(): AccountServices[];
    /**
     * Hot-swap the active account. Rewires the active pointer and emits
     * "active-changed" so any subscribers (module-level re-bindings, tray
     * updaters) can react. No service teardown — the prior account's
     * clients remain warm for future per-call routing.
     */
    setActive(accountId: string): Promise<void>;
    /**
     * Inject credentials freshly loaded from the OS keychain into every
     * account that currently has an empty password slot. Patches the in-memory
     * spec, the per-account SMTPService.config, and calls reinitialize() so
     * the SMTP transporter is rebuilt with the credentials. IMAP picks up the
     * new password automatically through connectAll() (which reads from the
     * patched spec).
     *
     * Context: credentials are stored in the OS keychain (under
     * service=mailpouch, account=bridge-password) rather than in the config
     * file so ~/.mailpouch.json can be mode-0600 without also being a plaintext
     * secret store. The AccountManager constructs services from the file-level
     * registry at module load, BEFORE main() has read the keychain, which
     * means every account spec starts with password = "". Without this
     * propagation step the SMTP transporter auths with empty credentials and
     * Bridge rejects with "Please configure the login" / "Missing credentials
     * for PLAIN". This is specifically the regression the multi-account
     * rollout introduced — the singleton-service world had module-level
     * reinitialize() reading a single shared config that main() populated
     * directly; per-account isolation broke that path.
     *
     * Accounts that already had a password (explicit in the file or
     * previously propagated) are left alone; passing an empty string does
     * nothing. Safe to call at boot after keychain load, and after every
     * settings-UI credential save.
     */
    applyKeychainCredentials(password: string, smtpToken?: string): void;
    /** Cleanly tear down every account's services. Called on shutdown. */
    closeAll(): Promise<void>;
    /**
     * Warm IMAP connections for every known account. Called at boot so IDLE
     * runs against every configured mailbox — otherwise non-active accounts
     * only connect on their first per-tool call, which means new-mail events
     * sit in the Proton server until the agent asks for them.
     *
     * Failures are logged per-account but do not stop the loop; a single
     * broken account shouldn't block the others. Returns per-account
     * success/failure so the caller can surface a summary.
     */
    connectAll(): Promise<Array<{
        id: string;
        ok: boolean;
        error?: string;
    }>>;
}
export declare function registerAccountManager(mgr: AccountManager): void;
export declare function getAccountManager(): AccountManager | null;
//# sourceMappingURL=manager.d.ts.map