import { onUnexpectedError } from './errors.js';
import { toDisposable } from './lifecycle.js';
import { ResourceMap } from './map.js';
import { isNative, webWorkerOrigin, isWeb } from './platform.js';
import { equalsIgnoreCase, startsWithIgnoreCase } from './strings.js';
import { URI } from './uri.js';
import { posix } from './path.js';
var Schemas;
( (function(Schemas) {
    Schemas.inMemory = 'inmemory';
    Schemas.vscode = 'vscode';
    Schemas.internal = 'private';
    Schemas.walkThrough = 'walkThrough';
    Schemas.walkThroughSnippet = 'walkThroughSnippet';
    Schemas.http = 'http';
    Schemas.https = 'https';
    Schemas.file = 'file';
    Schemas.mailto = 'mailto';
    Schemas.untitled = 'untitled';
    Schemas.data = 'data';
    Schemas.command = 'command';
    Schemas.vscodeRemote = 'vscode-remote';
    Schemas.vscodeRemoteResource = 'vscode-remote-resource';
    Schemas.vscodeManagedRemoteResource = 'vscode-managed-remote-resource';
    Schemas.vscodeUserData = 'vscode-userdata';
    Schemas.vscodeCustomEditor = 'vscode-custom-editor';
    Schemas.vscodeNotebookCell = 'vscode-notebook-cell';
    Schemas.vscodeNotebookCellMetadata = 'vscode-notebook-cell-metadata';
    Schemas.vscodeNotebookCellOutput = 'vscode-notebook-cell-output';
    Schemas.vscodeInteractiveInput = 'vscode-interactive-input';
    Schemas.vscodeSettings = 'vscode-settings';
    Schemas.vscodeWorkspaceTrust = 'vscode-workspace-trust';
    Schemas.vscodeTerminal = 'vscode-terminal';
    Schemas.vscodeChatCodeBlock = 'vscode-chat-code-block';
    Schemas.vscodeCopilotBackingChatCodeBlock = 'vscode-copilot-chat-code-block';
    Schemas.vscodeChatCodeCompareBlock = 'vscode-chat-code-compare-block';
    Schemas.vscodeChatSesssion = 'vscode-chat-editor';
    Schemas.webviewPanel = 'webview-panel';
    Schemas.vscodeWebview = 'vscode-webview';
    Schemas.extension = 'extension';
    Schemas.vscodeFileResource = 'vscode-file';
    Schemas.tmp = 'tmp';
    Schemas.vsls = 'vsls';
    Schemas.vscodeSourceControl = 'vscode-scm';
    Schemas.commentsInput = 'comment';
    Schemas.codeSetting = 'code-setting';
})(Schemas || (Schemas = {})));
function matchesScheme(target, scheme) {
    if (URI.isUri(target)) {
        return equalsIgnoreCase(target.scheme, scheme);
    }
    else {
        return startsWithIgnoreCase(target, scheme + ':');
    }
}
function matchesSomeScheme(target, ...schemes) {
    return ( schemes.some(scheme => matchesScheme(target, scheme)));
}
const connectionTokenQueryName = 'tkn';
class RemoteAuthoritiesImpl {
    constructor() {
        this._hosts = Object.create(null);
        this._ports = Object.create(null);
        this._connectionTokens = Object.create(null);
        this._preferredWebSchema = 'http';
        this._delegate = null;
        this._serverRootPath = '/';
    }
    setPreferredWebSchema(schema) {
        this._preferredWebSchema = schema;
    }
    setDelegate(delegate) {
        this._delegate = delegate;
    }
    setServerRootPath(product, serverBasePath) {
        this._serverRootPath = getServerRootPath(product, serverBasePath);
    }
    getServerRootPath() {
        return this._serverRootPath;
    }
    get _remoteResourcesPath() {
        return posix.join(this._serverRootPath, Schemas.vscodeRemoteResource);
    }
    set(authority, host, port) {
        this._hosts[authority] = host;
        this._ports[authority] = port;
    }
    setConnectionToken(authority, connectionToken) {
        this._connectionTokens[authority] = connectionToken;
    }
    getPreferredWebSchema() {
        return this._preferredWebSchema;
    }
    rewrite(uri) {
        if (this._delegate) {
            try {
                return this._delegate(uri);
            }
            catch (err) {
                onUnexpectedError(err);
                return uri;
            }
        }
        const authority = uri.authority;
        let host = this._hosts[authority];
        if (host && host.indexOf(':') !== -1 && host.indexOf('[') === -1) {
            host = `[${host}]`;
        }
        const port = this._ports[authority];
        const connectionToken = this._connectionTokens[authority];
        let query = `path=${encodeURIComponent(uri.path)}`;
        if (typeof connectionToken === 'string') {
            query += `&${connectionTokenQueryName}=${encodeURIComponent(connectionToken)}`;
        }
        return ( URI.from({
            scheme: isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
            authority: `${host}:${port}`,
            path: this._remoteResourcesPath,
            query
        }));
    }
}
const RemoteAuthorities = ( new RemoteAuthoritiesImpl());
function getServerRootPath(product, basePath) {
    return posix.join(basePath ?? '/', `${product.quality ?? 'oss'}-${product.commit ?? 'dev'}`);
}
const nodeModulesPath = 'vs/../../node_modules';
const nodeModulesAsarPath = 'vs/../../node_modules.asar';
const nodeModulesAsarUnpackedPath = 'vs/../../node_modules.asar.unpacked';
const VSCODE_AUTHORITY = 'vscode-app';
class FileAccessImpl {
    constructor() {
        this.staticBrowserUris = ( new ResourceMap());
        this.appResourcePathUrls = ( new Map());
        this.moduleContentProvider = ( new Map());
    }
    static { this.FALLBACK_AUTHORITY = VSCODE_AUTHORITY; }
    registerModuleContentProvider(moduleId, contentLoader) {
        this.moduleContentProvider.set(moduleId, contentLoader);
    }
    toModuleContent(moduleId) {
        return this.moduleContentProvider.get(moduleId)();
    }
    registerAppResourcePathUrl(moduleId, url) {
        this.appResourcePathUrls.set(moduleId, url);
    }
    toUrl(moduleId) {
        let url = this.appResourcePathUrls.get(moduleId);
        if (typeof url === 'function') {
            url = url();
        }
        return ( ( new URL(url ?? moduleId, globalThis.location?.href ?? import.meta.url)).toString());
    }
    asBrowserUri(resourcePath) {
        const uri = this.toUri(resourcePath, { toUrl: this.toUrl.bind(this) });
        return this.uriToBrowserUri(uri);
    }
    uriToBrowserUri(uri) {
        if (uri.scheme === Schemas.vscodeRemote) {
            return RemoteAuthorities.rewrite(uri);
        }
        if (
        uri.scheme === Schemas.file &&
            (
            (
            isNative || (webWorkerOrigin === `${Schemas.vscodeFileResource}://${FileAccessImpl.FALLBACK_AUTHORITY}`)))) {
            return uri.with({
                scheme: Schemas.vscodeFileResource,
                authority: uri.authority || FileAccessImpl.FALLBACK_AUTHORITY,
                query: null,
                fragment: null
            });
        }
        return this.staticBrowserUris.get(uri) ?? uri;
    }
    asFileUri(resourcePath) {
        const uri = this.toUri(resourcePath, { toUrl: this.toUrl.bind(this) });
        return this.uriToFileUri(uri);
    }
    uriToFileUri(uri) {
        if (uri.scheme === Schemas.vscodeFileResource) {
            return uri.with({
                scheme: Schemas.file,
                authority: uri.authority !== FileAccessImpl.FALLBACK_AUTHORITY ? uri.authority : null,
                query: null,
                fragment: null
            });
        }
        return uri;
    }
    toUri(uriOrModule, moduleIdToUrl) {
        if (URI.isUri(uriOrModule)) {
            return uriOrModule;
        }
        return ( URI.parse(moduleIdToUrl.toUrl(uriOrModule)));
    }
    registerStaticBrowserUri(uri, browserUri) {
        this.staticBrowserUris.set(uri, browserUri);
        return toDisposable(() => {
            if (this.staticBrowserUris.get(uri) === browserUri) {
                this.staticBrowserUris.delete(uri);
            }
        });
    }
    getRegisteredBrowserUris() {
        return ( this.staticBrowserUris.keys());
    }
}
const FileAccess = ( new FileAccessImpl());
var COI;
( (function(COI) {
    const coiHeaders = ( new Map([
        ['1', { 'Cross-Origin-Opener-Policy': 'same-origin' }],
        ['2', { 'Cross-Origin-Embedder-Policy': 'require-corp' }],
        ['3', { 'Cross-Origin-Opener-Policy': 'same-origin', 'Cross-Origin-Embedder-Policy': 'require-corp' }],
    ]));
    COI.CoopAndCoep = ( Object.freeze(coiHeaders.get('3')));
    const coiSearchParamName = 'vscode-coi';
    function getHeadersFromQuery(url) {
        let params;
        if (typeof url === 'string') {
            params = ( new URL(url)).searchParams;
        }
        else if (url instanceof URL) {
            params = url.searchParams;
        }
        else if (URI.isUri(url)) {
            params = ( new URL(( url.toString(true)))).searchParams;
        }
        const value = params?.get(coiSearchParamName);
        if (!value) {
            return undefined;
        }
        return coiHeaders.get(value);
    }
    COI.getHeadersFromQuery = getHeadersFromQuery;
    function addSearchParam(urlOrSearch, coop, coep) {
        if (!globalThis.crossOriginIsolated) {
            return;
        }
        const value = coop && coep ? '3' : coep ? '2' : '1';
        if (urlOrSearch instanceof URLSearchParams) {
            urlOrSearch.set(coiSearchParamName, value);
        }
        else {
            urlOrSearch[coiSearchParamName] = value;
        }
    }
    COI.addSearchParam = addSearchParam;
})(COI || (COI = {})));
export { COI, FileAccess, RemoteAuthorities, Schemas, VSCODE_AUTHORITY, connectionTokenQueryName, getServerRootPath, matchesScheme, matchesSomeScheme, nodeModulesAsarPath, nodeModulesAsarUnpackedPath, nodeModulesPath };
