/*
 * Copyright (C) 2016 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.ResourceQueryResult = class ResourceQueryResult
{
    constructor(resource, matches, cookie)
    {
        console.assert(matches.length, "Query matches list can't be empty.");

        this._resource = resource;
        this._matches = matches;
        this._cookie = cookie || null;
    }

    // Public

    get resource() { return this._resource; }
    get cookie() { return this._cookie; }

    get rank()
    {
        if (this._rank === undefined)
            this._calculateRank();

        return this._rank;
    }

    get matchingTextRanges()
    {
        if (!this._matchingTextRanges)
            this._matchingTextRanges = this._createMatchingTextRanges();

        return this._matchingTextRanges;
    }

    // Private

    _calculateRank()
    {
        const normalWeight = 10;
        const consecutiveWeight = 5;
        const specialMultiplier = 5;

        function getMultiplier(match) {
            if (match.type === WI.ResourceQueryMatch.Type.Special)
                return specialMultiplier;

            return 1;
        }

        this._rank = 0;

        let previousMatch = null;
        let consecutiveMatchStart = null;
        for (let match of this._matches) {
            this._rank += normalWeight * getMultiplier(match);

            let consecutive = previousMatch && previousMatch.index === match.index - 1;
            if (consecutive) {
                if (!consecutiveMatchStart)
                    consecutiveMatchStart = previousMatch;

                // If the first match in this consecutive series was a special character, give a
                // bonus (more likely to match a specific word in the text).  Otherwise, multiply
                // by the current length of the consecutive sequence (gives priority to fewer
                // longer sequences instead of more short sequences).
                this._rank += consecutiveWeight * getMultiplier(consecutiveMatchStart) * (match.index - consecutiveMatchStart.index);
            } else if (consecutiveMatchStart)
                consecutiveMatchStart = null;

            previousMatch = match;

            // The match index is deducted from the total rank, so matches that occur closer to
            // the beginning of the string are ranked higher.  Increase the amount subtracted if
            // the match is special, so as to favor matches towards the beginning of the string.
            if (!consecutive)
                this._rank -= match.index * getMultiplier(match);
        }
    }

    _createMatchingTextRanges()
    {
        if (!this._matches.length)
            return [];

        let ranges = [];
        let startIndex = this._matches[0].index;
        let endIndex = startIndex;
        for (let i = 1; i < this._matches.length; ++i) {
            let match = this._matches[i];

            // Increment endIndex for consecutive match.
            if (match.index === endIndex + 1) {
                endIndex++;
                continue;
            }

            // Begin a new range when a gap between this match and the previous match is found.
            ranges.push(new WI.TextRange(0, startIndex, 0, endIndex + 1));
            startIndex = match.index;
            endIndex = startIndex;
        }

        ranges.push(new WI.TextRange(0, startIndex, 0, endIndex + 1));
        return ranges;
    }

    // Testing

    __test_createMatchesMask()
    {
        let filename = this._resource.displayName;
        let lastIndex = -1;
        let result = "";

        for (let match of this._matches) {
            let gap = " ".repeat(match.index - lastIndex - 1);
            result += gap;
            result += filename[match.index];
            lastIndex = match.index;
        }

        return result;
    }
};
