/*
 * Copyright (C) 2013 Google 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.
 */

/**
 * @unrestricted
 */
Sources.FilePathScoreFunction = class {
  /**
   * @param {string} query
   */
  constructor(query) {
    this._query = query;
    this._queryUpperCase = query.toUpperCase();
    this._score = new Int32Array(20 * 100);
    this._sequence = new Int32Array(20 * 100);
    this._dataUpperCase = '';
    this._fileNameIndex = 0;
  }

  /**
   * @param {string} data
   * @param {?Array<number>} matchIndexes
   * @return {number}
   */
  score(data, matchIndexes) {
    if (!data || !this._query) {
      return 0;
    }
    const n = this._query.length;
    const m = data.length;
    if (!this._score || this._score.length < n * m) {
      this._score = new Int32Array(n * m * 2);
      this._sequence = new Int32Array(n * m * 2);
    }
    const score = this._score;
    const sequence = /** @type {!Int32Array} */ (this._sequence);
    this._dataUpperCase = data.toUpperCase();
    this._fileNameIndex = data.lastIndexOf('/');
    for (let i = 0; i < n; ++i) {
      for (let j = 0; j < m; ++j) {
        const skipCharScore = j === 0 ? 0 : score[i * m + j - 1];
        const prevCharScore = i === 0 || j === 0 ? 0 : score[(i - 1) * m + j - 1];
        const consecutiveMatch = i === 0 || j === 0 ? 0 : sequence[(i - 1) * m + j - 1];
        const pickCharScore = this._match(this._query, data, i, j, consecutiveMatch);
        if (pickCharScore && prevCharScore + pickCharScore >= skipCharScore) {
          sequence[i * m + j] = consecutiveMatch + 1;
          score[i * m + j] = (prevCharScore + pickCharScore);
        } else {
          sequence[i * m + j] = 0;
          score[i * m + j] = skipCharScore;
        }
      }
    }
    if (matchIndexes) {
      this._restoreMatchIndexes(sequence, n, m, matchIndexes);
    }
    const maxDataLength = 256;
    return score[n * m - 1] * maxDataLength + (maxDataLength - data.length);
  }

  /**
   * @param {string} data
   * @param {number} j
   * @return {boolean}
   */
  _testWordStart(data, j) {
    if (j === 0) {
      return true;
    }

    const prevChar = data.charAt(j - 1);
    return prevChar === '_' || prevChar === '-' || prevChar === '/' ||
        (data[j - 1] !== this._dataUpperCase[j - 1] && data[j] === this._dataUpperCase[j]);
  }

  /**
   * @param {!Int32Array} sequence
   * @param {number} n
   * @param {number} m
   * @param {!Array<number>} out
   */
  _restoreMatchIndexes(sequence, n, m, out) {
    let i = n - 1, j = m - 1;
    while (i >= 0 && j >= 0) {
      switch (sequence[i * m + j]) {
        case 0:
          --j;
          break;
        default:
          out.push(j);
          --i;
          --j;
          break;
      }
    }
    out.reverse();
  }

  /**
   * @param {string} query
   * @param {string} data
   * @param {number} i
   * @param {number} j
   * @return {number}
   */
  _singleCharScore(query, data, i, j) {
    const isWordStart = this._testWordStart(data, j);
    const isFileName = j > this._fileNameIndex;
    const isPathTokenStart = j === 0 || data[j - 1] === '/';
    const isCapsMatch = query[i] === data[j] && query[i] === this._queryUpperCase[i];
    let score = 10;
    if (isPathTokenStart) {
      score += 4;
    }
    if (isWordStart) {
      score += 2;
    }
    if (isCapsMatch) {
      score += 6;
    }
    if (isFileName) {
      score += 4;
    }
    // promote the case of making the whole match in the filename
    if (j === this._fileNameIndex + 1 && i === 0) {
      score += 5;
    }
    if (isFileName && isWordStart) {
      score += 3;
    }
    return score;
  }

  /**
   * @param {string} query
   * @param {string} data
   * @param {number} i
   * @param {number} j
   * @param {number} sequenceLength
   * @return {number}
   */
  _sequenceCharScore(query, data, i, j, sequenceLength) {
    const isFileName = j > this._fileNameIndex;
    const isPathTokenStart = j === 0 || data[j - 1] === '/';
    let score = 10;
    if (isFileName) {
      score += 4;
    }
    if (isPathTokenStart) {
      score += 5;
    }
    score += sequenceLength * 4;
    return score;
  }

  /**
   * @param {string} query
   * @param {string} data
   * @param {number} i
   * @param {number} j
   * @param {number} consecutiveMatch
   * @return {number}
   */
  _match(query, data, i, j, consecutiveMatch) {
    if (this._queryUpperCase[i] !== this._dataUpperCase[j]) {
      return 0;
    }

    if (!consecutiveMatch) {
      return this._singleCharScore(query, data, i, j);
    } else {
      return this._sequenceCharScore(query, data, i, j - consecutiveMatch, consecutiveMatch);
    }
  }
};
