"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.afterDefaultPluginsLoaded = exports.loadAndRunDefaultPlugins = exports.getDefaultPluginPathsAndSettings = void 0;
const immer_1 = require("immer");
const Setting_1 = require("../../../models/Setting");
const shim_1 = require("../../../shim");
const PluginService_1 = require("../PluginService");
const Logger_1 = require("@joplin/utils/Logger");
const path_1 = require("path");
const logger = Logger_1.default.create('defaultPluginsUtils');
// Use loadAndRunDefaultPlugins
// Exported for testing.
const getDefaultPluginPathsAndSettings = async (defaultPluginsDir, defaultPluginsInfo, pluginSettings, pluginService) => {
    const pluginPaths = [];
    if (!await shim_1.default.fsDriver().exists(defaultPluginsDir)) {
        logger.info(`Could not find default plugins' directory: ${defaultPluginsDir} - skipping installation.`);
        return { pluginPaths, pluginSettings };
    }
    const defaultPluginsPaths = await shim_1.default.fsDriver().readDirStats(defaultPluginsDir);
    if (defaultPluginsPaths.length <= 0) {
        logger.info(`Default plugins' directory is empty: ${defaultPluginsDir} - no default plugins will be installed.`);
    }
    for (const pluginStat of defaultPluginsPaths) {
        // Each plugin should be within a folder with the same ID as the plugin
        const pluginFileName = pluginStat.path;
        const pluginIdMatch = pluginFileName.match(/^(.*)+\.jpl$/);
        // Previously, default plugins were stored as
        //    default-plugin-id/plugin.jpl
        // We handle this case by skipping files that don't match the format
        //    default-plugin-id.jpl
        if (!pluginIdMatch) {
            logger.warn(`Default plugin filename ${pluginFileName} is not a .JPL file. Skipping.`);
            continue;
        }
        const pluginId = pluginIdMatch[1];
        if (!defaultPluginsInfo.hasOwnProperty(pluginId)) {
            logger.warn(`Default plugin ${pluginId} is missing in defaultPluginsInfo. Not loading.`);
            continue;
        }
        // We skip plugins that are already loaded -- attempting to unpack a different version of a plugin
        // that has already been loaded causes errors (see #9832).
        if (pluginService.isPluginLoaded(pluginId)) {
            logger.info(`Not loading default plugin ${pluginId} -- a plugin with the same ID is already loaded.`);
            continue;
        }
        pluginPaths.push((0, path_1.join)(defaultPluginsDir, pluginFileName));
        pluginSettings = (0, immer_1.produce)(pluginSettings, (draft) => {
            // Default plugins can be overridden but not uninstalled (as they're part of
            // the app bundle). When overriding and unoverriding a default plugin, the plugin's
            // state may be deleted.
            // As such, we recreate the plugin state if necessary.
            if (!draft[pluginId]) {
                draft[pluginId] = (0, PluginService_1.defaultPluginSetting)();
                const enabledByDefault = defaultPluginsInfo[pluginId].enabled;
                if (typeof enabledByDefault === 'boolean') {
                    draft[pluginId].enabled = enabledByDefault;
                }
            }
        });
    }
    return { pluginSettings, pluginPaths };
};
exports.getDefaultPluginPathsAndSettings = getDefaultPluginPathsAndSettings;
const loadAndRunDefaultPlugins = async (service, defaultPluginsDir, defaultPluginsInfo, originalPluginSettings) => {
    var _a;
    const { pluginPaths, pluginSettings } = (_a = await (0, exports.getDefaultPluginPathsAndSettings)(defaultPluginsDir, defaultPluginsInfo, originalPluginSettings, service)) !== null && _a !== void 0 ? _a : { pluginPaths: [], pluginSettings: originalPluginSettings };
    await service.loadAndRunPlugins(pluginPaths, pluginSettings, { builtIn: true, devMode: false });
    return pluginSettings;
};
exports.loadAndRunDefaultPlugins = loadAndRunDefaultPlugins;
// Applies setting overrides and marks default plugins as installed.
// Should be called after plugins have finished loading.
const afterDefaultPluginsLoaded = async (allLoadedPlugins, defaultPluginsInfo, pluginSettings) => {
    var _a;
    const installedDefaultPlugins = Setting_1.default.value('installedDefaultPlugins');
    const allDefaultPlugins = Object.keys(defaultPluginsInfo);
    const isFirstLoadOfDefaultPlugin = (pluginId) => {
        var _a, _b;
        // Not installed?
        if (!pluginSettings[pluginId]) {
            return false;
        }
        // Not the first load
        if (installedDefaultPlugins.includes(pluginId)) {
            return false;
        }
        // Return true only if the plugin is built-in (and not a user-installed
        // copy).
        //
        // This avoids overriding existing user-set settings.
        return (_b = (_a = allLoadedPlugins[pluginId]) === null || _a === void 0 ? void 0 : _a.builtIn) !== null && _b !== void 0 ? _b : false;
    };
    for (const pluginId of allDefaultPlugins) {
        // if pluginId is present in pluginSettings and not in installedDefaultPlugins array,
        // then it's a new default plugin and needs overrides applied.
        if (isFirstLoadOfDefaultPlugin(pluginId)) {
            // Postprocess: Apply setting overrides
            for (const settingName of Object.keys((_a = defaultPluginsInfo[pluginId].settings) !== null && _a !== void 0 ? _a : {})) {
                if (!installedDefaultPlugins.includes(pluginId) && Setting_1.default.keyExists(`plugin-${pluginId}.${settingName}`)) {
                    Setting_1.default.setValue(`plugin-${pluginId}.${settingName}`, defaultPluginsInfo[pluginId].settings[settingName]);
                }
            }
            // Mark the plugin as installed so that postprocessing won't be done again.
            Setting_1.default.setArrayValue('installedDefaultPlugins', pluginId);
        }
    }
};
exports.afterDefaultPluginsLoaded = afterDefaultPluginsLoaded;
//# sourceMappingURL=defaultPluginsUtils.js.map