/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
import { CancellationToken } from "../../../base/common/cancellation.mjs";
import { Event } from "../../../base/common/event.mjs";
import { IDisposable } from "../../../base/common/lifecycle.mjs";
import { OperatingSystem } from "../../../base/common/platform.mjs";
import { URI } from "../../../base/common/uri.mjs";
import { IConfigurationService } from "../../configuration/common/configuration.mjs";
import { ILogService } from "../../log/common/log.mjs";
import { IAddressProvider } from "../../remote/common/remoteAgentConnection.mjs";
import { TunnelPrivacy } from "../../remote/common/remoteAuthorityResolver.mjs";
export declare const ITunnelService: import("../../instantiation/common/instantiation.mjs").ServiceIdentifier<ITunnelService>;
export declare const ISharedTunnelsService: import("../../instantiation/common/instantiation.mjs").ServiceIdentifier<ISharedTunnelsService>;
export interface RemoteTunnel {
    readonly tunnelRemotePort: number;
    readonly tunnelRemoteHost: string;
    readonly tunnelLocalPort?: number;
    readonly localAddress: string;
    readonly privacy: string;
    readonly protocol?: string;
    dispose(silent?: boolean): Promise<void>;
}
export interface TunnelOptions {
    remoteAddress: {
        port: number;
        host: string;
    };
    localAddressPort?: number;
    label?: string;
    public?: boolean;
    privacy?: string;
    protocol?: string;
}
export declare enum TunnelProtocol {
    Http = "http",
    Https = "https"
}
export declare enum TunnelPrivacyId {
    ConstantPrivate = "constantPrivate",
    Private = "private",
    Public = "public"
}
export interface TunnelCreationOptions {
    elevationRequired?: boolean;
}
export interface TunnelProviderFeatures {
    elevation: boolean;
    /**
     * @deprecated
     */
    public?: boolean;
    privacyOptions: TunnelPrivacy[];
}
export interface ITunnelProvider {
    forwardPort(tunnelOptions: TunnelOptions, tunnelCreationOptions: TunnelCreationOptions): Promise<RemoteTunnel | undefined> | undefined;
}
export declare enum ProvidedOnAutoForward {
    Notify = 1,
    OpenBrowser = 2,
    OpenPreview = 3,
    Silent = 4,
    Ignore = 5,
    OpenBrowserOnce = 6
}
export interface ProvidedPortAttributes {
    port: number;
    autoForwardAction: ProvidedOnAutoForward;
}
export interface PortAttributesProvider {
    providePortAttributes(ports: number[], pid: number | undefined, commandLine: string | undefined, token: CancellationToken): Promise<ProvidedPortAttributes[]>;
}
export interface ITunnel {
    remoteAddress: {
        port: number;
        host: string;
    };
    /**
     * The complete local address(ex. localhost:1234)
     */
    localAddress: string;
    /**
     * @deprecated Use privacy instead
     */
    public?: boolean;
    privacy?: string;
    protocol?: string;
    /**
     * Implementers of Tunnel should fire onDidDispose when dispose is called.
     */
    onDidDispose: Event<void>;
    dispose(): Promise<void> | void;
}
export interface ISharedTunnelsService {
    readonly _serviceBrand: undefined;
    openTunnel(authority: string, addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded?: boolean, privacy?: string, protocol?: string): Promise<RemoteTunnel | undefined> | undefined;
}
export interface ITunnelService {
    readonly _serviceBrand: undefined;
    readonly tunnels: Promise<readonly RemoteTunnel[]>;
    readonly canChangePrivacy: boolean;
    readonly privacyOptions: TunnelPrivacy[];
    readonly onTunnelOpened: Event<RemoteTunnel>;
    readonly onTunnelClosed: Event<{
        host: string;
        port: number;
    }>;
    readonly canElevate: boolean;
    readonly hasTunnelProvider: boolean;
    readonly onAddedTunnelProvider: Event<void>;
    canTunnel(uri: URI): boolean;
    openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded?: boolean, privacy?: string, protocol?: string): Promise<RemoteTunnel | undefined> | undefined;
    getExistingTunnel(remoteHost: string, remotePort: number): Promise<RemoteTunnel | undefined>;
    setEnvironmentTunnel(remoteHost: string, remotePort: number, localAddress: string, privacy: string, protocol: string): void;
    closeTunnel(remoteHost: string, remotePort: number): Promise<void>;
    setTunnelProvider(provider: ITunnelProvider | undefined): IDisposable;
    setTunnelFeatures(features: TunnelProviderFeatures): void;
    isPortPrivileged(port: number): boolean;
}
export declare function extractLocalHostUriMetaDataForPortMapping(uri: URI): {
    address: string;
    port: number;
} | undefined;
export declare const LOCALHOST_ADDRESSES: string[];
export declare function isLocalhost(host: string): boolean;
export declare const ALL_INTERFACES_ADDRESSES: string[];
export declare function isAllInterfaces(host: string): boolean;
export declare function isPortPrivileged(port: number, host: string, os: OperatingSystem, osRelease: string): boolean;
export declare class DisposableTunnel {
    readonly remoteAddress: {
        port: number;
        host: string;
    };
    readonly localAddress: {
        port: number;
        host: string;
    } | string;
    private readonly _dispose;
    private _onDispose;
    onDidDispose: Event<void>;
    constructor(remoteAddress: {
        port: number;
        host: string;
    }, localAddress: {
        port: number;
        host: string;
    } | string, _dispose: () => Promise<void>);
    dispose(): Promise<void>;
}
export declare abstract class AbstractTunnelService implements ITunnelService {
    protected readonly logService: ILogService;
    protected readonly configurationService: IConfigurationService;
    readonly _serviceBrand: undefined;
    private _onTunnelOpened;
    onTunnelOpened: Event<RemoteTunnel>;
    private _onTunnelClosed;
    onTunnelClosed: Event<{
        host: string;
        port: number;
    }>;
    private _onAddedTunnelProvider;
    onAddedTunnelProvider: Event<void>;
    protected readonly _tunnels: Map<string, Map<number, {
        refcount: number;
        readonly value: Promise<RemoteTunnel | undefined>;
    }>>;
    protected _tunnelProvider: ITunnelProvider | undefined;
    protected _canElevate: boolean;
    private _privacyOptions;
    private _factoryInProgress;
    constructor(logService: ILogService, configurationService: IConfigurationService);
    get hasTunnelProvider(): boolean;
    protected get defaultTunnelHost(): string;
    setTunnelProvider(provider: ITunnelProvider | undefined): IDisposable;
    setTunnelFeatures(features: TunnelProviderFeatures): void;
    get canElevate(): boolean;
    get canChangePrivacy(): boolean;
    get privacyOptions(): TunnelPrivacy[];
    get tunnels(): Promise<readonly RemoteTunnel[]>;
    private getTunnels;
    dispose(): Promise<void>;
    setEnvironmentTunnel(remoteHost: string, remotePort: number, localAddress: string, privacy: string, protocol: string): void;
    getExistingTunnel(remoteHost: string, remotePort: number): Promise<RemoteTunnel | undefined>;
    openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded?: boolean, privacy?: string, protocol?: string): Promise<RemoteTunnel | undefined> | undefined;
    private makeTunnel;
    private tryDisposeTunnel;
    closeTunnel(remoteHost: string, remotePort: number): Promise<void>;
    protected addTunnelToMap(remoteHost: string, remotePort: number, tunnel: Promise<RemoteTunnel | undefined>): void;
    private removeEmptyTunnelFromMap;
    protected getTunnelFromMap(remoteHost: string, remotePort: number): {
        refcount: number;
        readonly value: Promise<RemoteTunnel | undefined>;
    } | undefined;
    canTunnel(uri: URI): boolean;
    abstract isPortPrivileged(port: number): boolean;
    protected abstract retainOrCreateTunnel(addressProvider: IAddressProvider, remoteHost: string, remotePort: number, localPort: number | undefined, elevateIfNeeded: boolean, privacy?: string, protocol?: string): Promise<RemoteTunnel | undefined> | undefined;
    protected createWithProvider(tunnelProvider: ITunnelProvider, remoteHost: string, remotePort: number, localPort: number | undefined, elevateIfNeeded: boolean, privacy?: string, protocol?: string): Promise<RemoteTunnel | undefined> | undefined;
}
