/**
 * @license
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import '../../shared/gr-autocomplete/gr-autocomplete.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../../../styles/shared-styles.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-search-bar_html.js';
import {URLEncodingBehavior} from '../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.js';
import {KeyboardShortcutBehavior} from '../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js';

// Possible static search options for auto complete, without negations.
const SEARCH_OPERATORS = [
  'added:',
  'age:',
  'age:1week', // Give an example age
  'assignee:',
  'author:',
  'branch:',
  'bug:',
  'cc:',
  'cc:self',
  'change:',
  'cherrypickof:',
  'comment:',
  'commentby:',
  'commit:',
  'committer:',
  'conflicts:',
  'deleted:',
  'delta:',
  'dir:',
  'directory:',
  'ext:',
  'extension:',
  'file:',
  'footer:',
  'from:',
  'has:',
  'has:draft',
  'has:edit',
  'has:star',
  'has:stars',
  'has:unresolved',
  'hashtag:',
  'intopic:',
  'is:',
  'is:abandoned',
  'is:assigned',
  'is:closed',
  'is:ignored',
  'is:merged',
  'is:open',
  'is:owner',
  'is:private',
  'is:reviewed',
  'is:reviewer',
  'is:starred',
  'is:submittable',
  'is:watched',
  'is:wip',
  'label:',
  'message:',
  'onlyexts:',
  'onlyextensions:',
  'owner:',
  'ownerin:',
  'parentproject:',
  'project:',
  'projects:',
  'query:',
  'ref:',
  'reviewedby:',
  'reviewer:',
  'reviewer:self',
  'reviewerin:',
  'size:',
  'star:',
  'status:',
  'status:abandoned',
  'status:closed',
  'status:merged',
  'status:open',
  'status:reviewed',
  'submissionid:',
  'topic:',
  'tr:',
];

// All of the ops, with corresponding negations.
const SEARCH_OPERATORS_WITH_NEGATIONS_SET =
  new Set(SEARCH_OPERATORS.concat(SEARCH_OPERATORS.map(op => `-${op}`)));

const MAX_AUTOCOMPLETE_RESULTS = 10;

const TOKENIZE_REGEX = /(?:[^\s"]+|"[^"]*")+\s*/g;

/**
 * @extends PolymerElement
 */
class GrSearchBar extends mixinBehaviors( [
  KeyboardShortcutBehavior,
  URLEncodingBehavior,
], GestureEventListeners(
    LegacyElementMixin(
        PolymerElement))) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-search-bar'; }
  /**
   * Fired when a search is committed
   *
   * @event handle-search
   */

  static get properties() {
    return {
      value: {
        type: String,
        value: '',
        notify: true,
        observer: '_valueChanged',
      },
      keyEventTarget: {
        type: Object,
        value() { return document.body; },
      },
      query: {
        type: Function,
        value() {
          return this._getSearchSuggestions.bind(this);
        },
      },
      projectSuggestions: {
        type: Function,
        value() {
          return () => Promise.resolve([]);
        },
      },
      groupSuggestions: {
        type: Function,
        value() {
          return () => Promise.resolve([]);
        },
      },
      accountSuggestions: {
        type: Function,
        value() {
          return () => Promise.resolve([]);
        },
      },
      _inputVal: String,
      _threshold: {
        type: Number,
        value: 1,
      },
    };
  }

  attached() {
    super.attached();
    this.$.restAPI.getConfig().then(serverConfig => {
      const mergeability = serverConfig
       && serverConfig.index
        && serverConfig.index.mergeabilityComputationBehavior;
      if (mergeability === 'API_REF_UPDATED_AND_CHANGE_REINDEX'
      || mergeability === 'REF_UPDATED_AND_CHANGE_REINDEX') {
        // add 'is:mergeable' to SEARCH_OPERATORS_WITH_NEGATIONS_SET
        this._addOperator('is:mergeable');
      }
    });
  }

  _addOperator(name, include_neg = true) {
    SEARCH_OPERATORS_WITH_NEGATIONS_SET.add(name);
    if (include_neg) {
      SEARCH_OPERATORS_WITH_NEGATIONS_SET.add(`-${name}`);
    }
  }

  keyboardShortcuts() {
    return {
      [this.Shortcut.SEARCH]: '_handleSearch',
    };
  }

  _valueChanged(value) {
    this._inputVal = value;
  }

  _handleInputCommit(e) {
    this._preventDefaultAndNavigateToInputVal(e);
  }

  /**
   * This function is called in a few different cases:
   *   - e.target is the search button
   *   - e.target is the gr-autocomplete widget (#searchInput)
   *   - e.target is the input element wrapped within #searchInput
   *
   * @param {!Event} e
   */
  _preventDefaultAndNavigateToInputVal(e) {
    e.preventDefault();
    const target = dom(e).rootTarget;
    // If the target is the #searchInput or has a sub-input component, that
    // is what holds the focus as opposed to the target from the DOM event.
    if (target.$.input) {
      target.$.input.blur();
    } else {
      target.blur();
    }
    const trimmedInput = this._inputVal && this._inputVal.trim();
    if (trimmedInput) {
      const predefinedOpOnlyQuery = [...SEARCH_OPERATORS_WITH_NEGATIONS_SET]
          .some(op => op.endsWith(':') && op === trimmedInput);
      if (predefinedOpOnlyQuery) {
        return;
      }
      this.dispatchEvent(new CustomEvent('handle-search', {
        detail: {inputVal: this._inputVal},
      }));
    }
  }

  /**
   * Determine what array of possible suggestions should be provided
   *     to _getSearchSuggestions.
   *
   * @param {string} input - The full search term, in lowercase.
   * @return {!Promise} This returns a promise that resolves to an array of
   *     suggestion objects.
   */
  _fetchSuggestions(input) {
    // Split the input on colon to get a two part predicate/expression.
    const splitInput = input.split(':');
    const predicate = splitInput[0];
    const expression = splitInput[1] || '';
    // Switch on the predicate to determine what to autocomplete.
    switch (predicate) {
      case 'ownerin':
      case 'reviewerin':
        // Fetch groups.
        return this.groupSuggestions(predicate, expression);

      case 'parentproject':
      case 'project':
        // Fetch projects.
        return this.projectSuggestions(predicate, expression);

      case 'author':
      case 'cc':
      case 'commentby':
      case 'committer':
      case 'from':
      case 'owner':
      case 'reviewedby':
      case 'reviewer':
        // Fetch accounts.
        return this.accountSuggestions(predicate, expression);

      default:
        return Promise.resolve([...SEARCH_OPERATORS_WITH_NEGATIONS_SET]
            .filter(operator => operator.includes(input))
            .map(operator => { return {text: operator}; }));
    }
  }

  /**
   * Get the sorted, pruned list of suggestions for the current search query.
   *
   * @param {string} input - The complete search query.
   * @return {!Promise} This returns a promise that resolves to an array of
   *     suggestions.
   */
  _getSearchSuggestions(input) {
    // Allow spaces within quoted terms.
    const tokens = input.match(TOKENIZE_REGEX);
    const trimmedInput = tokens[tokens.length - 1].toLowerCase();

    return this._fetchSuggestions(trimmedInput)
        .then(suggestions => {
          if (!suggestions || !suggestions.length) { return []; }
          return suggestions
              // Prioritize results that start with the input.
              .sort((a, b) => {
                const aContains = a.text.toLowerCase().indexOf(trimmedInput);
                const bContains = b.text.toLowerCase().indexOf(trimmedInput);
                if (aContains === bContains) {
                  return a.text.localeCompare(b.text);
                }
                if (aContains === -1) {
                  return 1;
                }
                if (bContains === -1) {
                  return -1;
                }
                return aContains - bContains;
              })
              // Return only the first {MAX_AUTOCOMPLETE_RESULTS} results.
              .slice(0, MAX_AUTOCOMPLETE_RESULTS - 1)
              // Map to an object to play nice with gr-autocomplete.
              .map(({text, label}) => {
                return {
                  name: text,
                  value: text,
                  label,
                };
              });
        });
  }

  _handleSearch(e) {
    const keyboardEvent = this.getKeyboardEvent(e);
    if (this.shouldSuppressKeyboardShortcut(e) ||
        (this.modifierPressed(e) && !keyboardEvent.shiftKey)) { return; }

    e.preventDefault();
    this.$.searchInput.focus();
    this.$.searchInput.selectAll();
  }
}

customElements.define(GrSearchBar.is, GrSearchBar);
