// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '/strings.m.js';
import { assertNotReached, assertNotReachedCase } from 'chrome://resources/js/assert.js';
import { loadTimeData } from 'chrome://resources/js/load_time_data.js';
// This `SafetyCheckWarningReason` enum should match the enum of the same
// name defined in the developer_private.webidl and enums.xml files.
export var SafetyCheckWarningReason;
(function (SafetyCheckWarningReason) {
    SafetyCheckWarningReason[SafetyCheckWarningReason["UNPUBLISHED"] = 1] = "UNPUBLISHED";
    SafetyCheckWarningReason[SafetyCheckWarningReason["POLICY"] = 2] = "POLICY";
    SafetyCheckWarningReason[SafetyCheckWarningReason["MALWARE"] = 3] = "MALWARE";
    SafetyCheckWarningReason[SafetyCheckWarningReason["OFFSTORE"] = 4] = "OFFSTORE";
    SafetyCheckWarningReason[SafetyCheckWarningReason["UNWANTED"] = 5] = "UNWANTED";
    SafetyCheckWarningReason[SafetyCheckWarningReason["NO_PRIVACY_PRACTICE"] = 6] = "NO_PRIVACY_PRACTICE";
})(SafetyCheckWarningReason || (SafetyCheckWarningReason = {}));
export var SourceType;
(function (SourceType) {
    SourceType["WEBSTORE"] = "webstore";
    SourceType["POLICY"] = "policy";
    SourceType["SIDELOADED"] = "sideloaded";
    SourceType["UNPACKED"] = "unpacked";
    SourceType["INSTALLED_BY_DEFAULT"] = "installed-by-default";
    SourceType["UNKNOWN"] = "unknown";
})(SourceType || (SourceType = {}));
export var EnableControl;
(function (EnableControl) {
    EnableControl["RELOAD"] = "RELOAD";
    EnableControl["REPAIR"] = "REPAIR";
    EnableControl["ENABLE_TOGGLE"] = "ENABLE_TOGGLE";
})(EnableControl || (EnableControl = {}));
// Duration of the toast shown.
export const TOAST_DURATION_MS = 3000;
/**
 * Returns true if the extension is enabled, including terminated
 * extensions.
 */
export function isEnabled(state) {
    switch (state) {
        case chrome.developerPrivate.ExtensionState.ENABLED:
        case chrome.developerPrivate.ExtensionState.TERMINATED:
            return true;
        case chrome.developerPrivate.ExtensionState.BLOCKLISTED:
        case chrome.developerPrivate.ExtensionState.DISABLED:
            return false;
        default:
            assertNotReachedCase(state);
    }
}
/**
 * @return Whether the user can change whether or not the extension is
 *     enabled.
 */
export function userCanChangeEnablement(item) {
    // User doesn't have permission.
    if (!item.userMayModify) {
        return false;
    }
    // Item is forcefully disabled.
    if (item.disableReasons.corruptInstall ||
        item.disableReasons.suspiciousInstall ||
        item.disableReasons.updateRequired ||
        item.disableReasons.publishedInStoreRequired ||
        item.disableReasons.blockedByPolicy ||
        item.disableReasons.unsupportedDeveloperExtension ||
        item.disableReasons.unsupportedManifestVersion) {
        return false;
    }
    // An item with dependent extensions can't be disabled (it would bork the
    // dependents).
    if (item.dependentExtensions.length > 0) {
        return false;
    }
    // Blocklisted can't be enabled, either.
    if (item.state === chrome.developerPrivate.ExtensionState.BLOCKLISTED) {
        return false;
    }
    return true;
}
export function getItemSource(item) {
    if (item.controlledInfo) {
        return SourceType.POLICY;
    }
    switch (item.location) {
        case chrome.developerPrivate.Location.THIRD_PARTY:
            return SourceType.SIDELOADED;
        case chrome.developerPrivate.Location.UNPACKED:
            return SourceType.UNPACKED;
        case chrome.developerPrivate.Location.UNKNOWN:
            return SourceType.UNKNOWN;
        case chrome.developerPrivate.Location.FROM_STORE:
            return SourceType.WEBSTORE;
        case chrome.developerPrivate.Location.INSTALLED_BY_DEFAULT:
            return SourceType.INSTALLED_BY_DEFAULT;
        default:
            assertNotReachedCase(item.location);
    }
}
export function getItemSourceString(source) {
    switch (source) {
        case SourceType.POLICY:
            return loadTimeData.getString('itemSourcePolicy');
        case SourceType.SIDELOADED:
            return loadTimeData.getString('itemSourceSideloaded');
        case SourceType.UNPACKED:
            return loadTimeData.getString('itemSourceUnpacked');
        case SourceType.WEBSTORE:
            return loadTimeData.getString('itemSourceWebstore');
        case SourceType.INSTALLED_BY_DEFAULT:
            return loadTimeData.getString('itemSourceInstalledByDefault');
        case SourceType.UNKNOWN:
            // Nothing to return. Calling code should use
            // chrome.developerPrivate.ExtensionInfo's |locationText| instead.
            return '';
        default:
            assertNotReachedCase(source);
    }
}
// This converter is used to convert the `SafetyCheckWarningReason` enum
// defined in the developer_private.webidl file for metrics logging
// reasons. It needs to be kept in sync with the corresponding enum in
// the developer_private.webidl and enums.xml files.
export function convertSafetyCheckReason(reason) {
    switch (reason) {
        case chrome.developerPrivate.SafetyCheckWarningReason.UNPUBLISHED: {
            return SafetyCheckWarningReason.UNPUBLISHED;
        }
        case chrome.developerPrivate.SafetyCheckWarningReason.POLICY: {
            return SafetyCheckWarningReason.POLICY;
        }
        case chrome.developerPrivate.SafetyCheckWarningReason.MALWARE: {
            return SafetyCheckWarningReason.MALWARE;
        }
        case chrome.developerPrivate.SafetyCheckWarningReason.OFFSTORE: {
            return SafetyCheckWarningReason.OFFSTORE;
        }
        case chrome.developerPrivate.SafetyCheckWarningReason.UNWANTED: {
            return SafetyCheckWarningReason.UNWANTED;
        }
        case chrome.developerPrivate.SafetyCheckWarningReason.NO_PRIVACY_PRACTICE: {
            return SafetyCheckWarningReason.NO_PRIVACY_PRACTICE;
        }
        default: {
            assertNotReachedCase(reason);
        }
    }
}
/**
 * Computes the human-facing label for the given inspectable view.
 */
export function computeInspectableViewLabel(view) {
    let label = view.url;
    // TODO(crbug.com/509552434): Investigate why view.url can have invalid URLs.
    try {
        // Trim the "chrome-extension://<id>/".
        const url = new URL(view.url);
        if (url.protocol === 'chrome-extension:') {
            label = url.pathname.substring(1);
        }
    }
    catch (e) {
    }
    if (label === '_generated_background_page.html') {
        label = loadTimeData.getString('viewBackgroundPage');
    }
    if (view.type === 'EXTENSION_SERVICE_WORKER_BACKGROUND') {
        label = loadTimeData.getString('viewServiceWorker');
    }
    // Add any qualifiers.
    if (view.incognito) {
        label += ' ' + loadTimeData.getString('viewIncognito');
    }
    if (view.renderProcessId === -1) {
        label += ' ' + loadTimeData.getString('viewInactive');
    }
    if (view.isIframe) {
        label += ' ' + loadTimeData.getString('viewIframe');
    }
    return label;
}
/**
 * Computes the accessible human-facing aria label for an extension toggle item.
 */
export function getEnableToggleAriaLabel(toggleEnabled, extensionsDataType, appEnabled, extensionEnabled, itemOff) {
    if (!toggleEnabled) {
        return itemOff;
    }
    const ExtensionType = chrome.developerPrivate.ExtensionType;
    switch (extensionsDataType) {
        case ExtensionType.HOSTED_APP:
        case ExtensionType.LEGACY_PACKAGED_APP:
        case ExtensionType.PLATFORM_APP:
            return appEnabled;
        case ExtensionType.EXTENSION:
        case ExtensionType.SHARED_MODULE:
            return extensionEnabled;
        case ExtensionType.THEME:
            assertNotReached('Don\'t send themes to the chrome://extensions page');
        default:
            assertNotReachedCase(extensionsDataType, 'Item type is not App or Extension.');
    }
}
/**
 * Clones the array and returns a new array with background pages and service
 * workers sorted before other views.
 * @returns Sorted array.
 */
export function sortViews(views) {
    function getSortValue(view) {
        switch (view.type) {
            case chrome.developerPrivate.ViewType.EXTENSION_SERVICE_WORKER_BACKGROUND:
                return 2;
            case chrome.developerPrivate.ViewType.EXTENSION_BACKGROUND_PAGE:
                return 1;
            default:
                return 0;
        }
    }
    return [...views].sort((a, b) => getSortValue(b) - getSortValue(a));
}
/**
 * @return Whether the extension is in the terminated state.
 */
function isTerminated(state) {
    return state === chrome.developerPrivate.ExtensionState.TERMINATED;
}
/**
 * Determines which enable control to display for a given extension.
 */
export function getEnableControl(data) {
    if (isTerminated(data.state)) {
        return EnableControl.RELOAD;
    }
    if (data.disableReasons.corruptInstall && data.userMayModify) {
        return EnableControl.REPAIR;
    }
    return EnableControl.ENABLE_TOGGLE;
}
export function createDummyExtensionInfo() {
    return {
        commands: [],
        isCommandRegistrationHandledExternally: false,
        dependentExtensions: [],
        description: '',
        disableReasons: {
            suspiciousInstall: false,
            corruptInstall: false,
            updateRequired: false,
            publishedInStoreRequired: false,
            blockedByPolicy: false,
            reloading: false,
            custodianApprovalRequired: false,
            parentDisabledPermissions: false,
            unsupportedManifestVersion: false,
            unsupportedDeveloperExtension: false,
        },
        errorCollection: { isEnabled: false, isActive: false },
        fileAccess: { isEnabled: false, isActive: false },
        fileAccessPendingChange: false,
        homePage: { url: '', specified: false },
        iconUrl: '',
        id: '',
        incognitoAccess: { isEnabled: false, isActive: false },
        userScriptsAccess: { isEnabled: false, isActive: false },
        incognitoAccessPendingChange: false,
        installWarnings: [],
        location: chrome.developerPrivate.Location.UNKNOWN,
        manifestErrors: [],
        manifestHomePageUrl: '',
        mustRemainInstalled: false,
        name: '',
        offlineEnabled: false,
        permissions: { simplePermissions: [] },
        runtimeErrors: [],
        runtimeWarnings: [],
        state: chrome.developerPrivate.ExtensionState.ENABLED,
        type: chrome.developerPrivate.ExtensionType.EXTENSION,
        updateUrl: '',
        userMayModify: false,
        version: '2.0',
        views: [],
        webStoreUrl: '',
        showSafeBrowsingAllowlistWarning: false,
        showAccessRequestsInToolbar: false,
        safetyCheckWarningReason: chrome.developerPrivate.SafetyCheckWarningReason.UNPUBLISHED,
        isAffectedByMV2Deprecation: false,
        canUploadAsAccountExtension: false,
    };
}
