
import { Platform } from '../../../base/common/platform.js';
import { PolicyCategory } from '../../../base/common/policy.js';
import { localize2, localize } from '../../../nls.js';
import { Extensions, ConfigurationScope } from '../../configuration/common/configurationRegistry.js';
import { TargetPlatform } from '../../extensions/common/extensions.js';
import { FileOperationResult } from '../../files/common/files.js';
import { Registry } from '../../registry/common/platform.js';

const EXTENSION_IDENTIFIER_PATTERN = "^([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$";
const EXTENSION_IDENTIFIER_REGEX = ( new RegExp(EXTENSION_IDENTIFIER_PATTERN));
const WEB_EXTENSION_TAG = "__web_extension";
const EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT = "skipWalkthrough";
const EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT = "skipPublisherTrust";
const EXTENSION_INSTALL_SOURCE_CONTEXT = "extensionInstallSource";
const EXTENSION_INSTALL_DEP_PACK_CONTEXT = "dependecyOrPackExtensionInstall";
var ExtensionInstallSource;
(function(ExtensionInstallSource) {
    ExtensionInstallSource["COMMAND"] = "command";
    ExtensionInstallSource["SETTINGS_SYNC"] = "settingsSync";
})(ExtensionInstallSource || (ExtensionInstallSource = {}));
function TargetPlatformToString(targetPlatform) {
    switch (targetPlatform) {
    case TargetPlatform.WIN32_X64:
        return "Windows 64 bit";
    case TargetPlatform.WIN32_ARM64:
        return "Windows ARM";
    case TargetPlatform.LINUX_X64:
        return "Linux 64 bit";
    case TargetPlatform.LINUX_ARM64:
        return "Linux ARM 64";
    case TargetPlatform.LINUX_ARMHF:
        return "Linux ARM";
    case TargetPlatform.ALPINE_X64:
        return "Alpine Linux 64 bit";
    case TargetPlatform.ALPINE_ARM64:
        return "Alpine ARM 64";
    case TargetPlatform.DARWIN_X64:
        return "Mac";
    case TargetPlatform.DARWIN_ARM64:
        return "Mac Silicon";
    case TargetPlatform.WEB:
        return "Web";
    case TargetPlatform.UNIVERSAL:
        return TargetPlatform.UNIVERSAL;
    case TargetPlatform.UNKNOWN:
        return TargetPlatform.UNKNOWN;
    case TargetPlatform.UNDEFINED:
        return TargetPlatform.UNDEFINED;
    }
}
function toTargetPlatform(targetPlatform) {
    switch (targetPlatform) {
    case TargetPlatform.WIN32_X64:
        return TargetPlatform.WIN32_X64;
    case TargetPlatform.WIN32_ARM64:
        return TargetPlatform.WIN32_ARM64;
    case TargetPlatform.LINUX_X64:
        return TargetPlatform.LINUX_X64;
    case TargetPlatform.LINUX_ARM64:
        return TargetPlatform.LINUX_ARM64;
    case TargetPlatform.LINUX_ARMHF:
        return TargetPlatform.LINUX_ARMHF;
    case TargetPlatform.ALPINE_X64:
        return TargetPlatform.ALPINE_X64;
    case TargetPlatform.ALPINE_ARM64:
        return TargetPlatform.ALPINE_ARM64;
    case TargetPlatform.DARWIN_X64:
        return TargetPlatform.DARWIN_X64;
    case TargetPlatform.DARWIN_ARM64:
        return TargetPlatform.DARWIN_ARM64;
    case TargetPlatform.WEB:
        return TargetPlatform.WEB;
    case TargetPlatform.UNIVERSAL:
        return TargetPlatform.UNIVERSAL;
    default:
        return TargetPlatform.UNKNOWN;
    }
}
function getTargetPlatform(platform, arch) {
    switch (platform) {
    case Platform.Windows:
        if (arch === "x64") {
            return TargetPlatform.WIN32_X64;
        }
        if (arch === "arm64") {
            return TargetPlatform.WIN32_ARM64;
        }
        return TargetPlatform.UNKNOWN;
    case Platform.Linux:
        if (arch === "x64") {
            return TargetPlatform.LINUX_X64;
        }
        if (arch === "arm64") {
            return TargetPlatform.LINUX_ARM64;
        }
        if (arch === "arm") {
            return TargetPlatform.LINUX_ARMHF;
        }
        return TargetPlatform.UNKNOWN;
    case "alpine":
        if (arch === "x64") {
            return TargetPlatform.ALPINE_X64;
        }
        if (arch === "arm64") {
            return TargetPlatform.ALPINE_ARM64;
        }
        return TargetPlatform.UNKNOWN;
    case Platform.Mac:
        if (arch === "x64") {
            return TargetPlatform.DARWIN_X64;
        }
        if (arch === "arm64") {
            return TargetPlatform.DARWIN_ARM64;
        }
        return TargetPlatform.UNKNOWN;
    case Platform.Web:
        return TargetPlatform.WEB;
    }
}
function isNotWebExtensionInWebTargetPlatform(allTargetPlatforms, productTargetPlatform) {
    return productTargetPlatform === TargetPlatform.WEB && !allTargetPlatforms.includes(TargetPlatform.WEB);
}
function isTargetPlatformCompatible(extensionTargetPlatform, allTargetPlatforms, productTargetPlatform) {
    if (isNotWebExtensionInWebTargetPlatform(allTargetPlatforms, productTargetPlatform)) {
        return false;
    }
    if (extensionTargetPlatform === TargetPlatform.UNDEFINED) {
        return true;
    }
    if (extensionTargetPlatform === TargetPlatform.UNIVERSAL) {
        return true;
    }
    if (extensionTargetPlatform === TargetPlatform.UNKNOWN) {
        return false;
    }
    if (extensionTargetPlatform === productTargetPlatform) {
        return true;
    }
    return false;
}
function isIExtensionIdentifier(obj) {
    const thing = obj;
    return !!thing && typeof thing === "object" && typeof thing.id === "string" && (!thing.uuid || typeof thing.uuid === "string");
}
var SortBy;
(function(SortBy) {
    SortBy["NoneOrRelevance"] = "NoneOrRelevance";
    SortBy["LastUpdatedDate"] = "LastUpdatedDate";
    SortBy["Title"] = "Title";
    SortBy["PublisherName"] = "PublisherName";
    SortBy["InstallCount"] = "InstallCount";
    SortBy["PublishedDate"] = "PublishedDate";
    SortBy["AverageRating"] = "AverageRating";
    SortBy["WeightedRating"] = "WeightedRating";
})(SortBy || (SortBy = {}));
var SortOrder;
(function(SortOrder) {
    SortOrder[SortOrder["Default"] = 0] = "Default";
    SortOrder[SortOrder["Ascending"] = 1] = "Ascending";
    SortOrder[SortOrder["Descending"] = 2] = "Descending";
})(SortOrder || (SortOrder = {}));
var FilterType;
(function(FilterType) {
    FilterType["Category"] = "Category";
    FilterType["ExtensionId"] = "ExtensionId";
    FilterType["ExtensionName"] = "ExtensionName";
    FilterType["ExcludeWithFlags"] = "ExcludeWithFlags";
    FilterType["Featured"] = "Featured";
    FilterType["SearchText"] = "SearchText";
    FilterType["Tag"] = "Tag";
    FilterType["Target"] = "Target";
})(FilterType || (FilterType = {}));
var StatisticType;
(function(StatisticType) {
    StatisticType["Install"] = "install";
    StatisticType["Uninstall"] = "uninstall";
})(StatisticType || (StatisticType = {}));
var InstallOperation;
(function(InstallOperation) {
    InstallOperation[InstallOperation["None"] = 1] = "None";
    InstallOperation[InstallOperation["Install"] = 2] = "Install";
    InstallOperation[InstallOperation["Update"] = 3] = "Update";
    InstallOperation[InstallOperation["Migrate"] = 4] = "Migrate";
})(InstallOperation || (InstallOperation = {}));
var ExtensionGalleryErrorCode;
(function(ExtensionGalleryErrorCode) {
    ExtensionGalleryErrorCode["Timeout"] = "Timeout";
    ExtensionGalleryErrorCode["Cancelled"] = "Cancelled";
    ExtensionGalleryErrorCode["ClientError"] = "ClientError";
    ExtensionGalleryErrorCode["ServerError"] = "ServerError";
    ExtensionGalleryErrorCode["Failed"] = "Failed";
    ExtensionGalleryErrorCode["DownloadFailedWriting"] = "DownloadFailedWriting";
    ExtensionGalleryErrorCode["Offline"] = "Offline";
})(ExtensionGalleryErrorCode || (ExtensionGalleryErrorCode = {}));
class ExtensionGalleryError extends Error {
    constructor(message, code) {
        super(message);
        this.code = code;
        this.name = code;
    }
}
var ExtensionManagementErrorCode;
(function(ExtensionManagementErrorCode) {
    ExtensionManagementErrorCode["NotFound"] = "NotFound";
    ExtensionManagementErrorCode["Unsupported"] = "Unsupported";
    ExtensionManagementErrorCode["Deprecated"] = "Deprecated";
    ExtensionManagementErrorCode["Malicious"] = "Malicious";
    ExtensionManagementErrorCode["Incompatible"] = "Incompatible";
    ExtensionManagementErrorCode["IncompatibleApi"] = "IncompatibleApi";
    ExtensionManagementErrorCode["IncompatibleTargetPlatform"] = "IncompatibleTargetPlatform";
    ExtensionManagementErrorCode["ReleaseVersionNotFound"] = "ReleaseVersionNotFound";
    ExtensionManagementErrorCode["Invalid"] = "Invalid";
    ExtensionManagementErrorCode["Download"] = "Download";
    ExtensionManagementErrorCode["DownloadSignature"] = "DownloadSignature";
    ExtensionManagementErrorCode["DownloadFailedWriting"] = "DownloadFailedWriting";
    ExtensionManagementErrorCode["UpdateMetadata"] = "UpdateMetadata";
    ExtensionManagementErrorCode["Extract"] = "Extract";
    ExtensionManagementErrorCode["Scanning"] = "Scanning";
    ExtensionManagementErrorCode["ScanningExtension"] = "ScanningExtension";
    ExtensionManagementErrorCode["ReadRemoved"] = "ReadRemoved";
    ExtensionManagementErrorCode["UnsetRemoved"] = "UnsetRemoved";
    ExtensionManagementErrorCode["Delete"] = "Delete";
    ExtensionManagementErrorCode["Rename"] = "Rename";
    ExtensionManagementErrorCode["IntializeDefaultProfile"] = "IntializeDefaultProfile";
    ExtensionManagementErrorCode["AddToProfile"] = "AddToProfile";
    ExtensionManagementErrorCode["InstalledExtensionNotFound"] = "InstalledExtensionNotFound";
    ExtensionManagementErrorCode["PostInstall"] = "PostInstall";
    ExtensionManagementErrorCode["CorruptZip"] = "CorruptZip";
    ExtensionManagementErrorCode["IncompleteZip"] = "IncompleteZip";
    ExtensionManagementErrorCode["PackageNotSigned"] = "PackageNotSigned";
    ExtensionManagementErrorCode["SignatureVerificationInternal"] = "SignatureVerificationInternal";
    ExtensionManagementErrorCode["SignatureVerificationFailed"] = "SignatureVerificationFailed";
    ExtensionManagementErrorCode["NotAllowed"] = "NotAllowed";
    ExtensionManagementErrorCode["Gallery"] = "Gallery";
    ExtensionManagementErrorCode["Cancelled"] = "Cancelled";
    ExtensionManagementErrorCode["Unknown"] = "Unknown";
    ExtensionManagementErrorCode["Internal"] = "Internal";
})(ExtensionManagementErrorCode || (ExtensionManagementErrorCode = {}));
var ExtensionSignatureVerificationCode;
(function(ExtensionSignatureVerificationCode) {
    ExtensionSignatureVerificationCode["NotSigned"] = "NotSigned";
    ExtensionSignatureVerificationCode["Success"] = "Success";
    ExtensionSignatureVerificationCode["RequiredArgumentMissing"] = "RequiredArgumentMissing";
    ExtensionSignatureVerificationCode["InvalidArgument"] = "InvalidArgument";
    ExtensionSignatureVerificationCode["PackageIsUnreadable"] = "PackageIsUnreadable";
    ExtensionSignatureVerificationCode["UnhandledException"] = "UnhandledException";
    ExtensionSignatureVerificationCode["SignatureManifestIsMissing"] = "SignatureManifestIsMissing";
    ExtensionSignatureVerificationCode["SignatureManifestIsUnreadable"] = "SignatureManifestIsUnreadable";
    ExtensionSignatureVerificationCode["SignatureIsMissing"] = "SignatureIsMissing";
    ExtensionSignatureVerificationCode["SignatureIsUnreadable"] = "SignatureIsUnreadable";
    ExtensionSignatureVerificationCode["CertificateIsUnreadable"] = "CertificateIsUnreadable";
    ExtensionSignatureVerificationCode["SignatureArchiveIsUnreadable"] = "SignatureArchiveIsUnreadable";
    ExtensionSignatureVerificationCode["FileAlreadyExists"] = "FileAlreadyExists";
    ExtensionSignatureVerificationCode["SignatureArchiveIsInvalidZip"] = "SignatureArchiveIsInvalidZip";
    ExtensionSignatureVerificationCode["SignatureArchiveHasSameSignatureFile"] = "SignatureArchiveHasSameSignatureFile";
    ExtensionSignatureVerificationCode["PackageIntegrityCheckFailed"] = "PackageIntegrityCheckFailed";
    ExtensionSignatureVerificationCode["SignatureIsInvalid"] = "SignatureIsInvalid";
    ExtensionSignatureVerificationCode["SignatureManifestIsInvalid"] = "SignatureManifestIsInvalid";
    ExtensionSignatureVerificationCode["SignatureIntegrityCheckFailed"] = "SignatureIntegrityCheckFailed";
    ExtensionSignatureVerificationCode["EntryIsMissing"] = "EntryIsMissing";
    ExtensionSignatureVerificationCode["EntryIsTampered"] = "EntryIsTampered";
    ExtensionSignatureVerificationCode["Untrusted"] = "Untrusted";
    ExtensionSignatureVerificationCode["CertificateRevoked"] = "CertificateRevoked";
    ExtensionSignatureVerificationCode["SignatureIsNotValid"] = "SignatureIsNotValid";
    ExtensionSignatureVerificationCode["UnknownError"] = "UnknownError";
    ExtensionSignatureVerificationCode["PackageIsInvalidZip"] = "PackageIsInvalidZip";
    ExtensionSignatureVerificationCode["SignatureArchiveHasTooManyEntries"] = "SignatureArchiveHasTooManyEntries";
})(
    ExtensionSignatureVerificationCode || (ExtensionSignatureVerificationCode = {})
);
class ExtensionManagementError extends Error {
    constructor(message, code) {
        super(message);
        this.code = code;
        this.name = code;
    }
}
const DISABLED_EXTENSIONS_STORAGE_PATH = "extensionsIdentifiers/disabled";
const ENABLED_EXTENSIONS_STORAGE_PATH = "extensionsIdentifiers/enabled";
async function computeSize(location, fileService) {
    let stat;
    try {
        stat = await fileService.resolve(location);
    } catch (e) {
        if (e.fileOperationResult === FileOperationResult.FILE_NOT_FOUND) {
            return 0;
        }
        throw e;
    }
    if (stat.children) {
        const sizes = await Promise.all(( stat.children.map(c => computeSize(c.resource, fileService))));
        return sizes.reduce((r, s) => r + s, 0);
    }
    return stat.size ?? 0;
}
const ExtensionsLocalizedLabel = ( localize2(1866, "Extensions"));
const PreferencesLocalizedLabel = ( localize2(1867, "Preferences"));
const AllowedExtensionsConfigKey = "extensions.allowed";
const VerifyExtensionSignatureConfigKey = "extensions.verifySignature";
const ExtensionRequestsTimeoutConfigKey = "extensions.requestTimeout";
( Registry.as(Extensions.Configuration)).registerConfiguration({
    id: "extensions",
    order: 30,
    title: ( localize(1868, "Extensions")),
    type: "object",
    properties: {
        [AllowedExtensionsConfigKey]: {
            type: "object",
            markdownDescription: ( localize(
                1869,
                "Specify a list of extensions that are allowed to use. This helps maintain a secure and consistent development environment by restricting the use of unauthorized extensions. For more information on how to configure this setting, please visit the [Configure Allowed Extensions](https://aka.ms/vscode/enterprise/extensions/allowed) section."
            )),
            default: "*",
            defaultSnippets: [{
                body: {},
                description: ( localize(1870, "No extensions are allowed."))
            }, {
                body: {
                    "*": true
                },
                description: ( localize(1871, "All extensions are allowed."))
            }],
            scope: ConfigurationScope.APPLICATION,
            policy: {
                name: "AllowedExtensions",
                category: PolicyCategory.Extensions,
                minimumVersion: "1.96",
                localization: {
                    description: {
                        key: "extensions.allowed.policy",
                        value: ( localize(
                            1872,
                            "Specify a list of extensions that are allowed to use. This helps maintain a secure and consistent development environment by restricting the use of unauthorized extensions. More information: https://aka.ms/vscode/enterprise/extensions/allowed"
                        ))
                    }
                }
            },
            additionalProperties: false,
            patternProperties: {
                "([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$": {
                    anyOf: [{
                        type: ["boolean", "string"],
                        enum: [true, false, "stable"],
                        description: ( localize(1873, "Allow or disallow the extension.")),
                        enumDescriptions: [( localize(1874, "Extension is allowed.")), ( localize(1875, "Extension is not allowed.")), ( localize(1876, "Allow only stable versions of the extension."))]
                    }, {
                        type: "array",
                        items: {
                            type: "string"
                        },
                        description: ( localize(
                            1877,
                            "Allow or disallow specific versions of the extension. To specifcy a platform specific version, use the format `platform@1.2.3`, e.g. `win32-x64@1.2.3`. Supported platforms are `win32-x64`, `win32-arm64`, `linux-x64`, `linux-arm64`, `linux-armhf`, `alpine-x64`, `alpine-arm64`, `darwin-x64`, `darwin-arm64`"
                        ))
                    }]
                },
                "([a-z0-9A-Z][a-z0-9-A-Z]*)$": {
                    type: ["boolean", "string"],
                    enum: [true, false, "stable"],
                    description: ( localize(1878, "Allow or disallow all extensions from the publisher.")),
                    enumDescriptions: [( localize(1879, "All extensions from the publisher are allowed.")), ( localize(1880, "All extensions from the publisher are not allowed.")), ( localize(1881, "Allow only stable versions of the extensions from the publisher."))]
                },
                "\\*": {
                    type: "boolean",
                    enum: [true, false],
                    description: ( localize(1882, "Allow or disallow all extensions.")),
                    enumDescriptions: [( localize(1883, "Allow all extensions.")), ( localize(1884, "Disallow all extensions."))]
                }
            }
        }
    }
});
function shouldRequireRepositorySignatureFor(isPrivate, galleryManifest) {
    if (isPrivate) {
        return galleryManifest?.capabilities.signing?.allPrivateRepositorySigned === true;
    }
    return galleryManifest?.capabilities.signing?.allPublicRepositorySigned === true;
}

export { AllowedExtensionsConfigKey, DISABLED_EXTENSIONS_STORAGE_PATH, ENABLED_EXTENSIONS_STORAGE_PATH, EXTENSION_IDENTIFIER_PATTERN, EXTENSION_IDENTIFIER_REGEX, EXTENSION_INSTALL_DEP_PACK_CONTEXT, EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT, EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT, EXTENSION_INSTALL_SOURCE_CONTEXT, ExtensionGalleryError, ExtensionGalleryErrorCode, ExtensionInstallSource, ExtensionManagementError, ExtensionManagementErrorCode, ExtensionRequestsTimeoutConfigKey, ExtensionSignatureVerificationCode, ExtensionsLocalizedLabel, FilterType, InstallOperation, PreferencesLocalizedLabel, SortBy, SortOrder, StatisticType, TargetPlatformToString, VerifyExtensionSignatureConfigKey, WEB_EXTENSION_TAG, computeSize, getTargetPlatform, isIExtensionIdentifier, isNotWebExtensionInWebTargetPlatform, isTargetPlatformCompatible, shouldRequireRepositorySignatureFor, toTargetPlatform };
