"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Extension = void 0;
const tslib_1 = require("tslib");
const di_1 = require("@opensumi/di");
const ide_core_browser_1 = require("@opensumi/ide-core-browser");
const static_resource_1 = require("@opensumi/ide-core-browser/lib/static-resource");
const const_1 = require("@opensumi/ide-core-common/lib/const");
const common_1 = require("../common");
const metadata_service_1 = require("./metadata.service");
const types_1 = require("./types");
const metaDataSymbol = Symbol.for('metaDataSymbol');
let Extension = class Extension extends ide_core_browser_1.WithEventBus {
    constructor(extensionData, isUseEnable, isBuiltin, isDevelopment) {
        super();
        this.extensionData = extensionData;
        this.isUseEnable = isUseEnable;
        this.isBuiltin = isBuiltin;
        this.isDevelopment = isDevelopment;
        this.extraMetadata = {};
        this._activated = false;
        this.logger = (0, ide_core_browser_1.getDebugLogger)();
        this.pkgLocalizedField = new Map();
        this._enabled = isUseEnable;
        this.packageJSON = this.extensionData.packageJSON;
        this.defaultPkgNlsJSON = this.extensionData.defaultPkgNlsJSON;
        this.packageNlsJSON = this.extensionData.packageNlsJSON;
        this.id = this.extensionData.id;
        this.extensionId = this.extensionData.extensionId;
        this.name = this.packageJSON.name;
        this.extraMetadata = this.extensionData.extraMetadata;
        this.path = this.extensionData.path;
        this.uri = this.extensionData.uri;
        this.realPath = this.extensionData.realPath;
        this.extendConfig = this.extensionData.extendConfig || {};
        this.enableProposedApi = Boolean(this.extensionData.packageJSON.enableProposedApi);
        // 这里还是直接用 this.uri，
        // 如果用 path, window 下路径为 C:\a，此时直接 parse 会变成 scheme 为 C 的 uri，转换不太对
        // 对于 node 层 extension.scanner 标准下 uri 为 file，纯前端下为自定义实现的 kt-ext，因此可直接使用
        // 不太确定为啥这里的 uri 类型为可选
        this.extensionLocation = this.staticResourceService.resolveStaticResource(ide_core_browser_1.URI.from(this.uri)).codeUri;
        this.initialize();
    }
    localize(key) {
        // 因为可能在没加载语言包之前就会获取 packageJson 的内容
        // 所以这里缓存的值可以会为 undefined 或者空字符串，这两者都属于无效内容
        // 对于无效内容要重新获取
        if (!this.pkgLocalizedField.get(key)) {
            const nlsValue = (0, ide_core_browser_1.replaceNlsField)(this.packageJSON[key], this.id);
            this.pkgLocalizedField.set(key, nlsValue);
            return nlsValue || this.packageJSON[key];
        }
        return this.pkgLocalizedField.get(key);
    }
    get activated() {
        return this._activated;
    }
    get enabled() {
        return this._enabled;
    }
    set enabled(enable) {
        this._enabled = enable;
    }
    get icon() {
        return this.packageJSON.icon && this.uri && this.extensionLocation.toString() + `/${this.packageJSON.icon}`;
    }
    async getDefaultIcon() {
        const registry = await this.extensionNodeClient.getOpenVSXRegistry();
        return registry + '/default-icon.png';
    }
    disable() {
        if (!this._enabled) {
            return;
        }
        this.extMetadataService.dispose();
        this._enabled = false;
        super.dispose();
    }
    enable() {
        if (this._enabled) {
            return;
        }
        this._enabled = true;
    }
    /**
     * 激活插件的 nls 语言包
     * 激活插件的 contributes 贡献点
     */
    initialize() {
        if (this._enabled) {
            this.addDispose(this.extMetadataService);
            if (this.packageNlsJSON) {
                (0, ide_core_browser_1.registerLocalizationBundle)({
                    ...(0, ide_core_browser_1.getCurrentLanguageInfo)(),
                    contents: this.packageNlsJSON,
                }, this.id);
            }
            if (this.defaultPkgNlsJSON) {
                (0, ide_core_browser_1.registerLocalizationBundle)({
                    languageId: 'default',
                    languageName: const_1.LOCALE_TYPES.EN_US,
                    localizedLanguageName: 'English',
                    contents: this.defaultPkgNlsJSON,
                }, this.id);
            }
            this.extMetadataService.initialize(this);
        }
    }
    async activate(visited = new Set()) {
        var _a;
        const deps = ((_a = this.packageJSON) === null || _a === void 0 ? void 0 : _a.extensionDependencies) || [];
        visited.add(this.extensionId);
        for (const dep of deps) {
            const nextDepId = typeof dep === 'string' ? dep : Object.keys(dep)[0];
            // in order to  break cycle
            // 循环依赖是不符合开发预期的行为，我们在这里直接跳过
            if (visited.has(nextDepId)) {
                continue;
            }
            const nextExt = this.extensionInstanceManageService.getExtensionInstanceByExtId(nextDepId);
            nextExt && (await nextExt.activate(visited));
        }
        if (this._activated) {
            return;
        }
        const skipActivate = await this.eventBus.fireAndAwait(new types_1.ExtensionWillActivateEvent(this));
        if (skipActivate.length > 0 && skipActivate[0].result) {
            this._activated = true;
            return Promise.resolve();
        }
        if (this._activating) {
            return this._activating.promise;
        }
        this._activating = new ide_core_browser_1.Deferred();
        this.extensionService
            .activeExtension(this)
            .then(() => {
            var _a;
            this._activated = true;
            this.eventBus.fire(new types_1.ExtensionDidActivatedEvent(this.toJSON()));
            (_a = this._activating) === null || _a === void 0 ? void 0 : _a.resolve();
        })
            .catch((e) => {
            var _a;
            this.logger.error(e);
            this._activated = false;
            (_a = this._activating) === null || _a === void 0 ? void 0 : _a.reject(e);
        });
        return this._activating.promise;
    }
    get contributes() {
        return this.packageJSON.contributes;
    }
    reset() {
        this._activated = false;
        this._activating = undefined;
    }
    get displayName() {
        return this.localize('displayName');
    }
    toJSON() {
        return {
            id: this.id,
            extensionId: this.extensionId,
            name: this.name,
            displayName: this.displayName,
            activated: this.activated,
            enabled: this.enabled,
            packageJSON: this.packageJSON,
            defaultPkgNlsJSON: this.defaultPkgNlsJSON,
            packageNlsJSON: this.packageNlsJSON,
            path: this.path,
            realPath: this.realPath,
            isUseEnable: this.isUseEnable,
            extendConfig: this.extendConfig,
            enableProposedApi: this.enableProposedApi,
            extraMetadata: this.extraMetadata,
            isBuiltin: this.isBuiltin,
            isDevelopment: this.isDevelopment,
            extensionLocation: this.extensionLocation,
        };
    }
};
exports.Extension = Extension;
tslib_1.__decorate([
    (0, di_1.Autowired)(metadata_service_1.ExtensionMetadataService),
    tslib_1.__metadata("design:type", metadata_service_1.ExtensionMetadataService)
], Extension.prototype, "extMetadataService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(common_1.ExtensionService),
    tslib_1.__metadata("design:type", common_1.ExtensionService)
], Extension.prototype, "extensionService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(),
    tslib_1.__metadata("design:type", static_resource_1.StaticResourceService)
], Extension.prototype, "staticResourceService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(types_1.AbstractExtInstanceManagementService),
    tslib_1.__metadata("design:type", types_1.AbstractExtInstanceManagementService)
], Extension.prototype, "extensionInstanceManageService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(common_1.ExtensionNodeServiceServerPath),
    tslib_1.__metadata("design:type", Object)
], Extension.prototype, "extensionNodeClient", void 0);
exports.Extension = Extension = tslib_1.__decorate([
    (0, di_1.Injectable)({ multiple: true }),
    tslib_1.__param(0, (0, di_1.Optional)(metaDataSymbol)),
    tslib_1.__param(1, (0, di_1.Optional)(Symbol())),
    tslib_1.__param(2, (0, di_1.Optional)(Symbol())),
    tslib_1.__param(3, (0, di_1.Optional)(Symbol())),
    tslib_1.__metadata("design:paramtypes", [Object, Boolean, Boolean, Boolean])
], Extension);
//# sourceMappingURL=extension.js.map