/*
 * Copyright (C) 2021 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.QueryResult = class QueryResult
{
    constructor(value, matches)
    {
        console.assert(matches.length, "Query matches list can't be empty.");

        this._value = value;
        this._matches = matches;
    }

    // Public

    get value() { return this._value; }

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

        return this._rank;
    }

    get 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.QueryMatch.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;
    }
};
