// Copyright (C) 2016 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.
(function() {
  'use strict';

  // 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:',
    'comment:',
    'commentby:',
    'commit:',
    'committer:',
    'conflicts:',
    'deleted:',
    'delta:',
    'file:',
    'from:',
    'has:',
    'has:draft',
    'has:edit',
    'has:star',
    'has:stars',
    'has:unresolved',
    'hashtag:',
    'intopic:',
    'is:',
    'is:abandoned',
    'is:assigned',
    'is:closed',
    'is:ignored',
    'is:mergeable',
    'is:merged',
    'is:open',
    'is:owner',
    'is:pending',
    'is:private',
    'is:reviewed',
    'is:reviewer',
    'is:starred',
    'is:watched',
    'is:wip',
    'label:',
    'message:',
    'owner:',
    'ownerin:',
    'parentproject:',
    'project:',
    'projects:',
    'query:',
    'ref:',
    'reviewedby:',
    'reviewer:',
    'reviewer:self',
    'reviewerin:',
    'size:',
    'star:',
    'status:',
    'status:abandoned',
    'status:closed',
    'status:merged',
    'status:open',
    'status:pending',
    'status:reviewed',
    'topic:',
    'tr:',
  ];

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

  const SELF_EXPRESSION = 'self';
  const ME_EXPRESSION = 'me';

  const MAX_AUTOCOMPLETE_RESULTS = 10;

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

  Polymer({
    is: 'gr-search-bar',

    behaviors: [
      Gerrit.AnonymousNameBehavior,
      Gerrit.KeyboardShortcutBehavior,
      Gerrit.URLEncodingBehavior,
    ],

    keyBindings: {
      '/': '_handleForwardSlashKey',
    },

    properties: {
      value: {
        type: String,
        value: '',
        notify: true,
        observer: '_valueChanged',
      },
      keyEventTarget: {
        type: Object,
        value() { return document.body; },
      },
      query: {
        type: Function,
        value() {
          return this._getSearchSuggestions.bind(this);
        },
      },
      _inputVal: String,
      _threshold: {
        type: Number,
        value: 1,
      },
      _config: Object,
    },

    attached() {
      this.$.restAPI.getConfig().then(cfg => {
        this._config = cfg;
      });
    },

    _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 = Polymer.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();
      }
      if (this._inputVal) {
        page.show('/q/' + this.encodeURL(this._inputVal, false));
      }
    },

    _accountOrAnon(name) {
      return this.getUserName(this._config, name, false);
    },

    /**
     * Fetch from the API the predicted accounts.
     * @param {string} predicate - The first part of the search term, e.g.
     *     'owner'
     * @param {string} expression - The second part of the search term, e.g.
     *     'kasp'
     * @return {!Promise} This returns a promise that resolves to an array of
     *     strings.
     */
    _fetchAccounts(predicate, expression) {
      if (expression.length === 0) { return Promise.resolve([]); }
      return this.$.restAPI.getSuggestedAccounts(
          expression,
          MAX_AUTOCOMPLETE_RESULTS)
          .then(accounts => {
            if (!accounts) { return []; }
            return accounts.map(acct => {
              if (acct.email) {
                return predicate + ':"' + this._accountOrAnon(acct) +
                    ' <' + acct.email + '>"';
              } else {
                return predicate + ':"' + this._accountOrAnon(acct) + '"';
              }
            });
          }).then(accounts => {
            // When the expression supplied is a beginning substring of 'self',
            // add it as an autocomplete option.
            if (SELF_EXPRESSION.startsWith(expression)) {
              return accounts.concat([predicate + ':' + SELF_EXPRESSION]);
            } else if (ME_EXPRESSION.startsWith(expression)) {
              return accounts.concat([predicate + ':' + ME_EXPRESSION]);
            } else {
              return accounts;
            }
          });
    },

    /**
     * Fetch from the API the predicted groups.
     * @param {string} predicate - The first part of the search term, e.g.
     *     'ownerin'
     * @param {string} expression - The second part of the search term, e.g.
     *     'polyger'
     * @return {!Promise} This returns a promise that resolves to an array of
     *     strings.
     */
    _fetchGroups(predicate, expression) {
      if (expression.length === 0) { return Promise.resolve([]); }
      return this.$.restAPI.getSuggestedGroups(
          expression,
          MAX_AUTOCOMPLETE_RESULTS)
          .then(groups => {
            if (!groups) { return []; }
            const keys = Object.keys(groups);
            return keys.map(key => predicate + ':' + key);
          });
    },

    /**
     * Fetch from the API the predicted projects.
     * @param {string} predicate - The first part of the search term, e.g.
     *     'project'
     * @param {string} expression - The second part of the search term, e.g.
     *     'gerr'
     * @return {!Promise} This returns a promise that resolves to an array of
     *     strings.
     */
    _fetchProjects(predicate, expression) {
      return this.$.restAPI.getSuggestedProjects(
          expression,
          MAX_AUTOCOMPLETE_RESULTS)
          .then(projects => {
            if (!projects) { return []; }
            const keys = Object.keys(projects);
            return keys.map(key => predicate + ':' + key);
          });
    },

    /**
     * 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
     *     strings.
     */
    _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._fetchGroups(predicate, expression);

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

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

        default:
          return Promise.resolve(SEARCH_OPERATORS_WITH_NEGATIONS
              .filter(operator => operator.includes(input)));
      }
    },

    /**
     * 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
     *     strings.
     */
    _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(operators => {
            if (!operators || !operators.length) { return []; }
            return operators
                // Prioritize results that start with the input.
                .sort((a, b) => {
                  const aContains = a.toLowerCase().indexOf(trimmedInput);
                  const bContains = b.toLowerCase().indexOf(trimmedInput);
                  if (aContains === bContains) {
                    return a.localeCompare(b);
                  }
                  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(operator => {
                  return {
                    name: operator,
                    value: operator,
                  };
                });
          });
    },

    _handleForwardSlashKey(e) {
      if (this.shouldSuppressKeyboardShortcut(e) ||
          this.modifierPressed(e)) { return; }

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