/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "../utils/markup"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.HTMLDataProvider = exports.browserNames = exports.BaselineImages = void 0;
    exports.getMissingBaselineBrowsers = getMissingBaselineBrowsers;
    exports.generateDocumentation = generateDocumentation;
    const markup_1 = require("../utils/markup");
    exports.BaselineImages = {
        BASELINE_LIMITED: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCA1NDAgMzAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzdHlsZT4KICAgIC5ncmF5LXNoYXBlIHsKICAgICAgZmlsbDogI0M2QzZDNjsgLyogTGlnaHQgbW9kZSAqLwogICAgfQoKICAgIEBtZWRpYSAocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspIHsKICAgICAgLmdyYXktc2hhcGUgewogICAgICAgIGZpbGw6ICM1NjU2NTY7IC8qIERhcmsgbW9kZSAqLwogICAgICB9CiAgICB9CiAgPC9zdHlsZT4KICA8cGF0aCBkPSJNMTUwIDBMMjQwIDkwTDIxMCAxMjBMMTIwIDMwTDE1MCAwWiIgZmlsbD0iI0YwOTQwOSIvPgogIDxwYXRoIGQ9Ik00MjAgMzBMNTQwIDE1MEw0MjAgMjcwTDM5MCAyNDBMNDgwIDE1MEwzOTAgNjBMNDIwIDMwWiIgY2xhc3M9ImdyYXktc2hhcGUiLz4KICA8cGF0aCBkPSJNMzMwIDE4MEwzMDAgMjEwTDM5MCAzMDBMNDIwIDI3MEwzMzAgMTgwWiIgZmlsbD0iI0YwOTQwOSIvPgogIDxwYXRoIGQ9Ik0xMjAgMzBMMTUwIDYwTDYwIDE1MEwxNTAgMjQwTDEyMCAyNzBMMCAxNTBMMTIwIDMwWiIgY2xhc3M9ImdyYXktc2hhcGUiLz4KICA8cGF0aCBkPSJNMzkwIDBMNDIwIDMwTDE1MCAzMDBMMTIwIDI3MEwzOTAgMFoiIGZpbGw9IiNGMDk0MDkiLz4KPC9zdmc+',
        BASELINE_LOW: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCA1NDAgMzAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzdHlsZT4KICAgIC5ibHVlLXNoYXBlIHsKICAgICAgZmlsbDogI0E4QzdGQTsgLyogTGlnaHQgbW9kZSAqLwogICAgfQoKICAgIEBtZWRpYSAocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspIHsKICAgICAgLmJsdWUtc2hhcGUgewogICAgICAgIGZpbGw6ICMyRDUwOUU7IC8qIERhcmsgbW9kZSAqLwogICAgICB9CiAgICB9CgogICAgLmRhcmtlci1ibHVlLXNoYXBlIHsKICAgICAgICBmaWxsOiAjMUI2RUYzOwogICAgfQoKICAgIEBtZWRpYSAocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspIHsKICAgICAgICAuZGFya2VyLWJsdWUtc2hhcGUgewogICAgICAgICAgICBmaWxsOiAjNDE4NUZGOwogICAgICAgIH0KICAgIH0KCiAgPC9zdHlsZT4KICA8cGF0aCBkPSJNMTUwIDBMMTgwIDMwTDE1MCA2MEwxMjAgMzBMMTUwIDBaIiBjbGFzcz0iYmx1ZS1zaGFwZSIvPgogIDxwYXRoIGQ9Ik0yMTAgNjBMMjQwIDkwTDIxMCAxMjBMMTgwIDkwTDIxMCA2MFoiIGNsYXNzPSJibHVlLXNoYXBlIi8+CiAgPHBhdGggZD0iTTQ1MCA2MEw0ODAgOTBMNDUwIDEyMEw0MjAgOTBMNDUwIDYwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNNTEwIDEyMEw1NDAgMTUwTDUxMCAxODBMNDgwIDE1MEw1MTAgMTIwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNNDUwIDE4MEw0ODAgMjEwTDQ1MCAyNDBMNDIwIDIxMEw0NTAgMTgwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNMzkwIDI0MEw0MjAgMjcwTDM5MCAzMDBMMzYwIDI3MEwzOTAgMjQwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNMzMwIDE4MEwzNjAgMjEwTDMzMCAyNDBMMzAwIDIxMEwzMzAgMTgwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNOTAgNjBMMTIwIDkwTDkwIDEyMEw2MCA5MEw5MCA2MFoiIGNsYXNzPSJibHVlLXNoYXBlIi8+CiAgPHBhdGggZD0iTTM5MCAwTDQyMCAzMEwxNTAgMzAwTDAgMTUwTDMwIDEyMEwxNTAgMjQwTDM5MCAwWiIgY2xhc3M9ImRhcmtlci1ibHVlLXNoYXBlIi8+Cjwvc3ZnPg==',
        BASELINE_HIGH: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCA1NDAgMzAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzdHlsZT4KICAgIC5ncmVlbi1zaGFwZSB7CiAgICAgIGZpbGw6ICNDNEVFRDA7IC8qIExpZ2h0IG1vZGUgKi8KICAgIH0KCiAgICBAbWVkaWEgKHByZWZlcnMtY29sb3Itc2NoZW1lOiBkYXJrKSB7CiAgICAgIC5ncmVlbi1zaGFwZSB7CiAgICAgICAgZmlsbDogIzEyNTIyNTsgLyogRGFyayBtb2RlICovCiAgICAgIH0KICAgIH0KICA8L3N0eWxlPgogIDxwYXRoIGQ9Ik00MjAgMzBMMzkwIDYwTDQ4MCAxNTBMMzkwIDI0MEwzMzAgMTgwTDMwMCAyMTBMMzkwIDMwMEw1NDAgMTUwTDQyMCAzMFoiIGNsYXNzPSJncmVlbi1zaGFwZSIvPgogIDxwYXRoIGQ9Ik0xNTAgMEwzMCAxMjBMNjAgMTUwTDE1MCA2MEwyMTAgMTIwTDI0MCA5MEwxNTAgMFoiIGNsYXNzPSJncmVlbi1zaGFwZSIvPgogIDxwYXRoIGQ9Ik0zOTAgMEw0MjAgMzBMMTUwIDMwMEwwIDE1MEwzMCAxMjBMMTUwIDI0MEwzOTAgMFoiIGZpbGw9IiMxRUE0NDYiLz4KPC9zdmc+'
    };
    function getEntryBaselineImage(status) {
        if (!status) {
            return '';
        }
        let baselineImg;
        switch (status?.baseline) {
            case 'low':
                baselineImg = exports.BaselineImages.BASELINE_LOW;
                break;
            case 'high':
                baselineImg = exports.BaselineImages.BASELINE_HIGH;
                break;
            default:
                baselineImg = exports.BaselineImages.BASELINE_LIMITED;
        }
        return `![Baseline icon](${baselineImg})`;
    }
    function getEntryBaselineStatus(status, browsers) {
        if (!status) {
            return '';
        }
        if (status.baseline === false) {
            const missingBrowsers = getMissingBaselineBrowsers(browsers);
            let status = `Limited availability across major browsers`;
            if (missingBrowsers) {
                status += ` (Not fully implemented in ${missingBrowsers})`;
            }
            return status;
        }
        const baselineYear = status.baseline_low_date?.split('-')[0];
        return `${status.baseline === 'low' ? 'Newly' : 'Widely'} available across major browsers (Baseline since ${baselineYear})`;
    }
    exports.browserNames = {
        'C': {
            name: 'Chrome',
            platform: 'desktop'
        },
        'CA': {
            name: 'Chrome',
            platform: 'Android'
        },
        'E': {
            name: 'Edge',
            platform: 'desktop'
        },
        'FF': {
            name: 'Firefox',
            platform: 'desktop'
        },
        'FFA': {
            name: 'Firefox',
            platform: 'Android'
        },
        'S': {
            name: 'Safari',
            platform: 'macOS'
        },
        'SM': {
            name: 'Safari',
            platform: 'iOS'
        }
    };
    const shortCompatPattern = /(E|FFA|FF|SM|S|CA|C|IE|O)([\d|\.]+)?/;
    // TODO: Remove "as any" when tsconfig supports es2021+
    const missingBaselineBrowserFormatter = new Intl.ListFormat("en", {
        style: "long",
        type: "disjunction",
    });
    /**
     * Input is like [E12, FF28, FM28, C29, CM29, IE11, O16]
     * Output is like `Safari`
     */
    function getMissingBaselineBrowsers(browsers) {
        if (!browsers) {
            return '';
        }
        const missingBrowsers = new Map(Object.entries(exports.browserNames));
        for (const shortCompatString of browsers) {
            const match = shortCompatPattern.exec(shortCompatString);
            if (!match) {
                continue;
            }
            const browser = match[1];
            missingBrowsers.delete(browser);
        }
        return missingBaselineBrowserFormatter.format(Object.values(Array.from(missingBrowsers.entries()).reduce((browsers, [browserId, browser]) => {
            if (browser.name in browsers || browserId === 'E') {
                browsers[browser.name] = browser.name;
                return browsers;
            }
            // distinguish between platforms when applicable 
            browsers[browser.name] = `${browser.name} on ${browser.platform}`;
            return browsers;
        }, {})));
    }
    class HTMLDataProvider {
        isApplicable() {
            return true;
        }
        /**
         * Currently, unversioned data uses the V1 implementation
         * In the future when the provider handles multiple versions of HTML custom data,
         * use the latest implementation for unversioned data
         */
        constructor(id, customData) {
            this.id = id;
            this._tags = [];
            this._tagMap = {};
            this._valueSetMap = {};
            this._tags = customData.tags || [];
            this._globalAttributes = customData.globalAttributes || [];
            this._tags.forEach(t => {
                this._tagMap[t.name.toLowerCase()] = t;
            });
            if (customData.valueSets) {
                customData.valueSets.forEach(vs => {
                    this._valueSetMap[vs.name] = vs.values;
                });
            }
        }
        getId() {
            return this.id;
        }
        provideTags() {
            return this._tags;
        }
        provideAttributes(tag) {
            const attributes = [];
            const processAttribute = (a) => {
                attributes.push(a);
            };
            const tagEntry = this._tagMap[tag.toLowerCase()];
            if (tagEntry) {
                tagEntry.attributes.forEach(processAttribute);
            }
            this._globalAttributes.forEach(processAttribute);
            return attributes;
        }
        provideValues(tag, attribute) {
            const values = [];
            attribute = attribute.toLowerCase();
            const processAttributes = (attributes) => {
                attributes.forEach(a => {
                    if (a.name.toLowerCase() === attribute) {
                        if (a.values) {
                            a.values.forEach(v => {
                                values.push(v);
                            });
                        }
                        if (a.valueSet) {
                            if (this._valueSetMap[a.valueSet]) {
                                this._valueSetMap[a.valueSet].forEach(v => {
                                    values.push(v);
                                });
                            }
                        }
                    }
                });
            };
            const tagEntry = this._tagMap[tag.toLowerCase()];
            if (tagEntry) {
                processAttributes(tagEntry.attributes);
            }
            processAttributes(this._globalAttributes);
            return values;
        }
    }
    exports.HTMLDataProvider = HTMLDataProvider;
    /**
     * Generate Documentation used in hover/complete
     * From `documentation` and `references`
     */
    function generateDocumentation(item, settings = {}, doesSupportMarkdown) {
        const result = {
            kind: doesSupportMarkdown ? 'markdown' : 'plaintext',
            value: ''
        };
        if (item.description && settings.documentation !== false) {
            const normalizedDescription = (0, markup_1.normalizeMarkupContent)(item.description);
            if (normalizedDescription) {
                result.value += normalizedDescription.value;
            }
        }
        if (item.status && settings.documentation !== false) {
            if (result.value.length) {
                result.value += `\n\n`;
            }
            const baselineStatus = getEntryBaselineStatus(item.status, item.browsers);
            if (doesSupportMarkdown) {
                result.value += `${getEntryBaselineImage(item.status)} _${baselineStatus}_`;
            }
            else {
                result.value += baselineStatus;
            }
        }
        if (item.references && item.references.length > 0 && settings.references !== false) {
            if (result.value.length) {
                result.value += `\n\n`;
            }
            if (doesSupportMarkdown) {
                result.value += item.references.map(r => {
                    return `[${r.name}](${r.url})`;
                }).join(' | ');
            }
            else {
                result.value += item.references.map(r => {
                    return `${r.name}: ${r.url}`;
                }).join('\n');
            }
        }
        if (result.value === '') {
            return undefined;
        }
        return result;
    }
});
