// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { isAndroid, isIOS } from './platform.js';
/**
 * @return The scale factors supported by this platform for webui resources.
 */
function getSupportedScaleFactors() {
    const supportedScaleFactors = [];
    if (!isIOS) {
        // This matches the code in ResourceBundle::InitSharedInstance() that
        // supports SCALE_FACTOR_100P on all non-iOS platforms.
        supportedScaleFactors.push(1);
    }
    if (!isIOS && !isAndroid) {
        // All desktop platforms support zooming which also updates the renderer's
        // device scale factors (a.k.a devicePixelRatio), and these platforms have
        // high DPI assets for 2x.  Let the renderer pick the closest image for
        // the current device scale factor.
        supportedScaleFactors.push(2);
    }
    else {
        // For other platforms that use fixed device scale factor, use
        // the window's device pixel ratio.
        // TODO(oshima): Investigate corresponding to
        // ResourceBundle::InitSharedInstance() more closely.
        supportedScaleFactors.push(window.devicePixelRatio);
    }
    return supportedScaleFactors;
}
/**
 * Generates a CSS url string.
 * @param s The URL to generate the CSS url for.
 * @return The CSS url string.
 */
export function getUrlForCss(s) {
    // http://www.w3.org/TR/css3-values/#uris
    // Parentheses, commas, whitespace characters, single quotes (') and double
    // quotes (") appearing in a URI must be escaped with a backslash
    const s2 = s.replace(/(\(|\)|\,|\s|\'|\"|\\)/g, '\\$1');
    return `url("${s2}")`;
}
/**
 * A URL for the filetype icon for |filePath|. OS and theme dependent.
 */
export function getFileIconUrl(filePath) {
    const url = new URL('chrome://fileicon/');
    url.searchParams.set('path', filePath);
    url.searchParams.set('scale', window.devicePixelRatio + 'x');
    return url.toString();
}
/**
 * Generates a CSS image-set for a chrome:// url.
 * An entry in the image set is added for each of getSupportedScaleFactors().
 * The scale-factor-specific url is generated by replacing the first instance
 * of 'scalefactor' in |path| with the numeric scale factor.
 *
 * @param path The URL to generate an image set for.
 *     'scalefactor' should be a substring of |path|.
 * @return The CSS image-set.
 */
function getImageSet(path) {
    const supportedScaleFactors = getSupportedScaleFactors();
    const replaceStartIndex = path.indexOf('SCALEFACTOR');
    if (replaceStartIndex < 0) {
        return getUrlForCss(path);
    }
    let s = '';
    for (let i = 0; i < supportedScaleFactors.length; ++i) {
        const scaleFactor = supportedScaleFactors[i];
        const pathWithScaleFactor = path.substr(0, replaceStartIndex) +
            scaleFactor + path.substr(replaceStartIndex + 'scalefactor'.length);
        s += getUrlForCss(pathWithScaleFactor) + ' ' + scaleFactor + 'x';
        if (i !== supportedScaleFactors.length - 1) {
            s += ', ';
        }
    }
    return 'image-set(' + s + ')';
}
/**
 * Returns the URL of the image, or an image set of URLs for the provided
 * path.  Resources in chrome://theme have multiple supported scale factors.
 *
 * @param path The path of the image.
 * @return The url, or an image set of URLs.
 */
export function getImage(path) {
    const chromeThemePath = 'chrome://theme';
    const isChromeThemeUrl = (path.slice(0, chromeThemePath.length) === chromeThemePath);
    return isChromeThemeUrl ? getImageSet(path + '@SCALEFACTORx') :
        getUrlForCss(path);
}
function getBaseFaviconUrl() {
    const faviconUrl = new URL('chrome://favicon2/');
    faviconUrl.searchParams.set('size', '16');
    faviconUrl.searchParams.set('scaleFactor', 'SCALEFACTORx');
    return faviconUrl;
}
/**
 * Creates a CSS image-set for a favicon.
 *
 * @param url URL of the favicon
 * @return image-set for the favicon
 */
export function getFavicon(url) {
    const faviconUrl = getBaseFaviconUrl();
    faviconUrl.searchParams.set('iconUrl', url);
    return getImageSet(faviconUrl.toString());
}
function getDefaultFaviconUrlParams() {
    return {
        isSyncedUrlForHistoryUi: false,
        remoteIconUrlForUma: '',
        size: 16,
        forceLightMode: false,
        fallbackToHost: true,
        forceEmptyDefaultFavicon: false,
        scaleFactor: '',
    };
}
/**
 * Creates a favicon request URL based on the given parameters.
 *
 * @param url URL of the original page
 * @param optionalParams Options object that specifies additional parameters to
 *     configure the favicon request URL that's constructed by this function.
 *
 * @return URL for the favicon request.
 */
export function getFaviconUrl(url, optionalParams) {
    const params = Object.assign(getDefaultFaviconUrlParams(), optionalParams);
    // Note: URL param keys used below must match those in the description of
    // chrome://favicon2 format in components/favicon_base/favicon_url_parser.h.
    const faviconUrl = getBaseFaviconUrl();
    faviconUrl.searchParams.set('pageUrl', url);
    faviconUrl.searchParams.set('size', params.size.toString());
    // TODO(dbeam): use the presence of 'allowGoogleServerFallback' to
    // indicate true, otherwise false.
    const fallback = params.isSyncedUrlForHistoryUi ? '1' : '0';
    faviconUrl.searchParams.set('allowGoogleServerFallback', fallback);
    if (params.isSyncedUrlForHistoryUi) {
        faviconUrl.searchParams.set('iconUrl', params.remoteIconUrlForUma);
    }
    if (params.forceLightMode) {
        faviconUrl.searchParams.set('forceLightMode', 'true');
    }
    if (!params.fallbackToHost) {
        faviconUrl.searchParams.set('fallbackToHost', '0');
    }
    if (params.forceEmptyDefaultFavicon) {
        faviconUrl.searchParams.set('forceEmptyDefaultFavicon', '1');
    }
    if (params.scaleFactor) {
        faviconUrl.searchParams.set('scaleFactor', params.scaleFactor);
    }
    return faviconUrl.toString();
}
/**
 * Creates a CSS image-set for a favicon request based on a page URL.
 *
 * @param url URL of the original page
 * @param isSyncedUrlForHistoryUi Should be set to true only if the
 *     caller is an UI aimed at displaying user history, and the requested url
 *     is known to be present in Chrome sync data.
 * @param remoteIconUrlForUma In case the entry is contained in sync
 *     data, we can pass the associated icon url.
 * @param size The favicon size.
 * @param forceLightMode Flag to force the service to show the light
 *     mode version of the default favicon.
 * @param fallbackToHost To allow for disabling the best match fallback
 *     behavior.
 * @param forceEmptyDefaultFavicon Flag to force the service to return an empty
 *     image as the default favicon.
 * @param scaleFactor The scale factor for the requested favicon (e.g. '2x').
 *
 * @return image-set for the favicon.
 */
export function getFaviconForPageURL(url, isSyncedUrlForHistoryUi, remoteIconUrlForUma = '', size = 16, forceLightMode = false, fallbackToHost = true, forceEmptyDefaultFavicon = false, scaleFactor = '') {
    return getImageSet(getFaviconUrl(url, {
        isSyncedUrlForHistoryUi,
        remoteIconUrlForUma,
        size,
        forceLightMode,
        fallbackToHost,
        forceEmptyDefaultFavicon,
        scaleFactor,
    }));
}
