/*
 * Copyright (C) 2010 Nikita Vasilyev. All rights reserved.
 * Copyright (C) 2010 Joseph Pecoraro. All rights reserved.
 * Copyright (C) 2010 Google Inc. All rights reserved.
 * Copyright (C) 2013 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.CSSCompletions = class CSSCompletions
{
    constructor(properties, acceptEmptyPrefix)
    {
        this._values = [];
        this._shorthands = {};

        // The `properties` parameter can be either a list of objects with 'name' / 'longhand'
        // properties when initialized from the protocol for CSSCompletions.cssNameCompletions.
        // Or it may just a list of strings when quickly initialized for other completion purposes.
        if (properties.length && typeof properties[0] === "string")
            this._values = this._values.concat(properties);
        else {
            for (var property of properties) {
                var propertyName = property.name;
                console.assert(propertyName);

                this._values.push(propertyName);

                let aliases = property.aliases;
                if (aliases)
                    this._values = this._values.concat(aliases);

                var longhands = property.longhands;
                if (longhands) {
                    for (var j = 0; j < longhands.length; ++j) {
                        var longhandName = longhands[j];

                        var shorthands = this._shorthands[longhandName];
                        if (!shorthands) {
                            shorthands = [];
                            this._shorthands[longhandName] = shorthands;
                        }

                        shorthands.push(propertyName);
                    }
                }
            }
        }

        this._values.sort();

        this._acceptEmptyPrefix = acceptEmptyPrefix;
    }

    // Static

    static initializeCSSCompletions(target)
    {
        console.assert(target.CSSAgent);

        if (WI.CSSCompletions.cssNameCompletions)
            return;

        function propertyNamesCallback(error, names)
        {
            if (error)
                return;

            WI.CSSCompletions.cssNameCompletions = new WI.CSSCompletions(names, false);

            WI.CSSKeywordCompletions.addCustomCompletions(names);

            // CodeMirror is not included by tests so we shouldn't assume it always exists.
            // If it isn't available we skip MIME type associations.
            if (!window.CodeMirror)
                return;

            var propertyNamesForCodeMirror = {};
            var valueKeywordsForCodeMirror = {"inherit": true, "initial": true, "unset": true, "revert": true, "var": true, "env": true};
            var colorKeywordsForCodeMirror = {};

            function nameForCodeMirror(name)
            {
                // CodeMirror parses the vendor prefix separate from the property or keyword name,
                // so we need to strip vendor prefixes from our names. Also strip function parenthesis.
                return name.replace(/^-[^-]+-/, "").replace(/\(\)$/, "").toLowerCase();
            }

            function collectPropertyNameForCodeMirror(propertyName)
            {
                // Properties can also be value keywords, like when used in a transition.
                // So we add them to both lists.
                var codeMirrorPropertyName = nameForCodeMirror(propertyName);
                propertyNamesForCodeMirror[codeMirrorPropertyName] = true;
                valueKeywordsForCodeMirror[codeMirrorPropertyName] = true;
            }

            for (var property of names)
                collectPropertyNameForCodeMirror(property.name);

            for (var propertyName in WI.CSSKeywordCompletions._propertyKeywordMap) {
                var keywords = WI.CSSKeywordCompletions._propertyKeywordMap[propertyName];
                for (var i = 0; i < keywords.length; ++i) {
                    // Skip numbers, like the ones defined for font-weight.
                    if (keywords[i] === WI.CSSKeywordCompletions.AllPropertyNamesPlaceholder || !isNaN(Number(keywords[i])))
                        continue;
                    valueKeywordsForCodeMirror[nameForCodeMirror(keywords[i])] = true;
                }
            }

            WI.CSSKeywordCompletions._colors.forEach(function(colorName) {
                colorKeywordsForCodeMirror[nameForCodeMirror(colorName)] = true;
            });

            function updateCodeMirrorCSSMode(mimeType)
            {
                var modeSpec = CodeMirror.resolveMode(mimeType);

                console.assert(modeSpec.propertyKeywords);
                console.assert(modeSpec.valueKeywords);
                console.assert(modeSpec.colorKeywords);

                modeSpec.propertyKeywords = propertyNamesForCodeMirror;
                modeSpec.valueKeywords = valueKeywordsForCodeMirror;
                modeSpec.colorKeywords = colorKeywordsForCodeMirror;

                CodeMirror.defineMIME(mimeType, modeSpec);
            }

            updateCodeMirrorCSSMode("text/css");
            updateCodeMirrorCSSMode("text/x-scss");
        }

        function fontFamilyNamesCallback(error, fontFamilyNames)
        {
            if (error)
                return;

            WI.CSSKeywordCompletions.addPropertyCompletionValues("font-family", fontFamilyNames);
            WI.CSSKeywordCompletions.addPropertyCompletionValues("font", fontFamilyNames);
        }

        target.CSSAgent.getSupportedCSSProperties(propertyNamesCallback);

        // COMPATIBILITY (iOS 9): CSS.getSupportedSystemFontFamilyNames did not exist.
        if (target.CSSAgent.getSupportedSystemFontFamilyNames)
            target.CSSAgent.getSupportedSystemFontFamilyNames(fontFamilyNamesCallback);
    }

    static completeUnbalancedValue(value)
    {
        const State = {
            Data: 0,
            SingleQuoteString: 1,
            DoubleQuoteString: 2,
            Comment: 3
        };

        let state = State.Data;
        let unclosedParenthesisCount = 0;
        let trailingBackslash = false;
        let length = value.length;

        for (let i = 0; i < length; ++i) {
            switch (value[i]) {
            case "'":
                if (state === State.Data)
                    state = State.SingleQuoteString;
                else if (state === State.SingleQuoteString)
                    state = State.Data;
                break;

            case "\"":
                if (state === State.Data)
                    state = State.DoubleQuoteString;
                else if (state === State.DoubleQuoteString)
                    state = State.Data;
                break;

            case "(":
                if (state === State.Data)
                    ++unclosedParenthesisCount;
                break;

            case ")":
                if (state === State.Data && unclosedParenthesisCount)
                    --unclosedParenthesisCount;
                break;

            case "/":
                if (state === State.Data) {
                    if (value[i + 1] === "*")
                        state = State.Comment;
                }
                break;

            case "\\":
                if (i === length - 1)
                    trailingBackslash = true;
                else
                    ++i; // Skip next character.
                break;

            case "*":
                if (state === State.Comment) {
                    if (value[i + 1] === "/")
                        state = State.Data;
                }
                break;
            }
        }

        let suffix = "";

        if (trailingBackslash)
            suffix += "\\";

        switch (state) {
        case State.SingleQuoteString:
            suffix += "'";
            break;
        case State.DoubleQuoteString:
            suffix += "\"";
            break;
        case State.Comment:
            suffix += "*/";
            break;
        }

        suffix += ")".repeat(unclosedParenthesisCount);

        return suffix;
    }

    // Public

    get values()
    {
        return this._values;
    }

    startsWith(prefix)
    {
        if (!prefix)
            return this._acceptEmptyPrefix ? this._values.slice() : [];

        let firstIndex = this._firstIndexOfPrefix(prefix);
        if (firstIndex === -1)
            return [];

        let results = [];
        while (firstIndex < this._values.length && this._values[firstIndex].startsWith(prefix))
            results.push(this._values[firstIndex++]);
        return results;
    }

    _firstIndexOfPrefix(prefix)
    {
        if (!this._values.length)
            return -1;
        if (!prefix)
            return this._acceptEmptyPrefix ? 0 : -1;

        var maxIndex = this._values.length - 1;
        var minIndex = 0;
        var foundIndex;

        do {
            var middleIndex = (maxIndex + minIndex) >> 1;
            if (this._values[middleIndex].startsWith(prefix)) {
                foundIndex = middleIndex;
                break;
            }
            if (this._values[middleIndex] < prefix)
                minIndex = middleIndex + 1;
            else
                maxIndex = middleIndex - 1;
        } while (minIndex <= maxIndex);

        if (foundIndex === undefined)
            return -1;

        while (foundIndex && this._values[foundIndex - 1].startsWith(prefix))
            foundIndex--;

        return foundIndex;
    }

    next(str, prefix)
    {
        return this._closest(str, prefix, 1);
    }

    previous(str, prefix)
    {
        return this._closest(str, prefix, -1);
    }

    _closest(str, prefix, shift)
    {
        if (!str)
            return "";

        var index = this._values.indexOf(str);
        if (index === -1)
            return "";

        if (!prefix) {
            index = (index + this._values.length + shift) % this._values.length;
            return this._values[index];
        }

        var propertiesWithPrefix = this.startsWith(prefix);
        var j = propertiesWithPrefix.indexOf(str);
        j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length;
        return propertiesWithPrefix[j];
    }

    isShorthandPropertyName(shorthand)
    {
        return WI.CSSKeywordCompletions.LonghandNamesForShorthandProperty.has(shorthand);
    }

    shorthandsForLonghand(longhand)
    {
        return this._shorthands[longhand] || [];
    }

    isValidPropertyName(name)
    {
        return this._values.includes(name);
    }
};

WI.CSSCompletions.cssNameCompletions = null;
