/**
 * Copyright (c) OpenLens Maintainers. All rights reserved.
 * Licensed under MIT License. See LICENSE in root directory for more information.
 */
import type { ExtensionLoader } from "../extension-loader";
import type { InstalledExtension, LensExtensionId, LensExtensionManifest, ExternalInstalledExtension } from "@openlens/legacy-extensions";
import type { ExtensionInstallationStateStore } from "../extension-installation-state-store/extension-installation-state-store";
import type { ReadJson } from "../../common/fs/read-json-file.injectable";
import type { Logger } from "@openlens/logger";
import type { PathExists } from "../../common/fs/path-exists.injectable";
import type { Watch } from "../../common/fs/watch/watch.injectable";
import type { LStat } from "../../common/fs/lstat.injectable";
import type { ReadDirectory } from "../../common/fs/read-directory.injectable";
import type { EnsureDirectory } from "../../common/fs/ensure-dir.injectable";
import type { AccessPath } from "../../common/fs/access-path.injectable";
import type { Copy } from "../../common/fs/copy.injectable";
import type { JoinPaths } from "../../common/path/join-paths.injectable";
import type { GetBasenameOfPath } from "../../common/path/get-basename.injectable";
import type { GetDirnameOfPath } from "../../common/path/get-dirname.injectable";
import type { GetRelativePath } from "../../common/path/get-relative-path.injectable";
import type { RemovePath } from "../../common/fs/remove.injectable";
import type TypedEventEmitter from "typed-emitter";
import type { IsExtensionEnabled } from "../../features/extensions/enabled/common/is-enabled.injectable";
interface Dependencies {
    readonly extensionLoader: ExtensionLoader;
    readonly extensionInstallationStateStore: ExtensionInstallationStateStore;
    readonly extensionPackageRootDirectory: string;
    readonly resourcesDirectory: string;
    readonly logger: Logger;
    readonly isProduction: boolean;
    readonly fileSystemSeparator: string;
    readonly homeDirectoryPath: string;
    isExtensionEnabled: IsExtensionEnabled;
    isCompatibleExtension: (manifest: LensExtensionManifest) => boolean;
    installExtension: (name: string) => Promise<void>;
    readJsonFile: ReadJson;
    pathExists: PathExists;
    removePath: RemovePath;
    lstat: LStat;
    watch: Watch;
    readDirectory: ReadDirectory;
    ensureDirectory: EnsureDirectory;
    accessPath: AccessPath;
    copy: Copy;
    joinPaths: JoinPaths;
    getBasenameOfPath: GetBasenameOfPath;
    getDirnameOfPath: GetDirnameOfPath;
    getRelativePath: GetRelativePath;
}
export declare const manifestFilename = "package.json";
interface ExtensionDiscoveryChannelMessage {
    isLoaded: boolean;
}
interface ExtensionDiscoveryEvents {
    add: (ext: InstalledExtension) => void;
    remove: (extId: LensExtensionId) => void;
}
/**
 * Discovers installed bundled and local extensions from the filesystem.
 * Also watches for added and removed local extensions by watching the directory.
 * Uses ExtensionInstaller to install dependencies for all of the extensions.
 * This is also done when a new extension is copied to the local extensions directory.
 * .init() must be called to start the directory watching.
 * The class emits events for added and removed extensions:
 * - "add": When extension is added. The event is of type InstalledExtension
 * - "remove": When extension is removed. The event is of type LensExtensionId
 */
export declare class ExtensionDiscovery {
    protected readonly dependencies: Dependencies;
    protected bundledFolderPath: string;
    private loadStarted;
    private extensions;
    isLoaded: boolean;
    get whenLoaded(): Promise<void> & {
        cancel(): void;
    };
    readonly events: TypedEventEmitter<ExtensionDiscoveryEvents>;
    constructor(dependencies: Dependencies);
    get localFolderPath(): string;
    get packageJsonPath(): string;
    get nodeModulesPath(): string;
    /**
     * Initializes the class and setups the file watcher for added/removed local extensions.
     */
    init(): Promise<void>;
    initRenderer(): Promise<void>;
    initMain(): Promise<void>;
    private _watch;
    /**
     * Watches for added/removed local extensions.
     * Dependencies are installed automatically after an extension folder is copied.
     */
    watchExtensions(): Promise<void>;
    stopWatchingExtensions(): Promise<void>;
    handleWatchFileAdd: (manifestPath: string) => Promise<void>;
    /**
     * Handle any unlink event, filtering out non-package.json links so the delete code
     * only happens once per extension.
     * @param filePath The absolute path to either a folder or file in the extensions folder
     */
    handleWatchUnlinkEvent: (filePath: string) => Promise<void>;
    /**
     * Remove the symlink under node_modules if exists.
     * If we don't remove the symlink, the uninstall would leave a non-working symlink,
     * which wouldn't be fixed if the extension was reinstalled, causing the extension not to work.
     * @param name e.g. "@mirantis/lens-extension-cc"
     */
    removeSymlinkByPackageName(name: string): Promise<void>;
    /**
     * Uninstalls extension.
     * The application will detect the folder unlink and remove the extension from the UI automatically.
     * @param extensionId The ID of the extension to uninstall.
     */
    uninstallExtension(extensionId: LensExtensionId): Promise<void>;
    load(): Promise<Map<LensExtensionId, InstalledExtension>>;
    /**
     * Returns the symlinked path to the extension folder,
     * e.g. "/Users/<username>/Library/Application Support/Lens/node_modules/@publisher/extension"
     */
    protected getInstalledPath(name: string): string;
    /**
     * Returns the symlinked path to the package.json,
     * e.g. "/Users/<username>/Library/Application Support/Lens/node_modules/@publisher/extension/package.json"
     */
    protected getInstalledManifestPath(name: string): string;
    /**
     * Returns InstalledExtension from path to package.json file.
     * Also updates this.packagesJson.
     */
    protected loadExtensionFromFolder(folderPath: string): Promise<ExternalInstalledExtension | null>;
    ensureExtensions(): Promise<Map<LensExtensionId, ExternalInstalledExtension>>;
    loadFromFolder(folderPath: string): Promise<ExternalInstalledExtension[]>;
    toJSON(): ExtensionDiscoveryChannelMessage;
    broadcast(): void;
}
export {};
