<!--
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.
-->

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/iron-input/iron-input.html">
<link rel="import" href="../behaviors/keyboard-shortcut-behavior.html">
<link rel="import" href="gr-ajax.html">
<link rel="import" href="gr-button.html">
<link rel="import" href="gr-request.html">

<dom-module id="gr-reviewer-list">
  <style>
    :host {
      display: block;
    }
    :host([disabled]) {
      opacity: .8;
      pointer-events: none;
    }
    .autocompleteContainer {
      position: relative;
    }
    .inputContainer {
      display: flex;
      margin-top: .25em;
    }
    .inputContainer input {
      flex: 1;
      font: inherit;
    }
    .dropdown {
      background-color: #fff;
      box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
      position: absolute;
      left: 0;
      top: 100%;
    }
    .dropdown .reviewer {
      cursor: pointer;
      padding: .5em .75em;
    }
    .dropdown .reviewer[selected] {
      background-color: #ccc;
    }
    .remove,
    .cancel {
      color: #999;
    }
    .remove {
      font-size: .9em;
    }
    .cancel {
      font-size: 2em;
      line-height: 1;
      padding: 0 .15em;
      text-decoration: none;
    }
  </style>
  <template>
    <gr-ajax id="autocompleteXHR"
        url="[[_computeAutocompleteURL(change)]]"
        params="[[_computeAutocompleteParams(_inputVal)]]"
        on-response="_handleResponse"></gr-ajax>

    <template is="dom-repeat" items="[[_reviewers]]" as="reviewer">
      <div class="reviewer">
        <gr-account-link account="[[reviewer]]" show-email></gr-account-link>
        <gr-button link
            class="remove"
            data-account-id$="[[reviewer._account_id]]"
            on-tap="_handleRemoveTap"
            hidden$="[[_computeCannotRemoveReviewer(reviewer, mutable)]]">remove</gr-buttom>
      </div>
    </template>
    <div class="controlsContainer" hidden$="[[!mutable]]">
      <div class="autocompleteContainer" hidden$="[[!_showInput]]">
        <div class="inputContainer">
          <input is="iron-input" id="input"
              bind-value="{{_inputVal}}" disabled$="[[disabled]]">
          <gr-button link class="cancel" on-tap="_handleCancelTap">×</gr-button>
        </div>
        <div class="dropdown" hidden$="[[_hideAutocomplete]]">
          <template is="dom-repeat" items="[[_autocompleteData]]" as="reviewer">
            <div class="reviewer"
                data-index$="[[index]]"
                on-mouseenter="_handleMouseEnterItem"
                on-tap="_handleItemTap"
                selected$="[[_computeSelected(index, _selectedIndex)]]">
              <template is="dom-if" if="[[reviewer.account]]">
                <gr-account-label
                    account="[[reviewer.account]]" show-email></gr-account-label>
              </template>
              <template is="dom-if" if="[[reviewer.group]]">
                <span>[[reviewer.group.name]] (group)</span>
              </template>
            </div>
          </template>
        </div>
      </div>
      <gr-button link id="addReviewer" class="addReviewer" on-tap="_handleAddTap"
          hidden$="[[_showInput]]">Add reviewer</gr-button>
    </div>
  </template>
  <script>
  (function() {
    'use strict';

    Polymer({
      is: 'gr-reviewer-list',

      properties: {
        change: Object,
        mutable: {
          type: Boolean,
          value: false,
        },
        disabled: {
          type: Boolean,
          value: false,
          reflectToAttribute: true,
        },
        suggestFrom: {
          type: Number,
          value: 3,
        },

        _reviewers: {
          type: Array,
          value: function() { return []; },
        },
        _autocompleteData: {
          type: Array,
          value: function() { return []; },
          observer: '_autocompleteDataChanged',
        },
        _inputVal: {
          type: String,
          value: '',
          observer: '_inputValChanged',
        },
        _inputRequestHandle: Number,
        _inputRequestTimeout: {
          type: Number,
          value: 250,
        },
        _showInput: {
          type: Boolean,
          value: false,
        },
        _hideAutocomplete: {
          type: Boolean,
          value: true,
          observer: '_hideAutocompleteChanged',
        },
        _selectedIndex: {
          type: Number,
          value: 0,
        },
        _boundBodyClickHandler: {
          type: Function,
          value: function() {
            return this._handleBodyClick.bind(this);
          },
        },

        // Used for testing.
        _lastAutocompleteRequest: Object,
        _xhrPromise: Object,
      },

      behaviors: [
        Gerrit.KeyboardShortcutBehavior,
      ],

      observers: [
        '_reviewersChanged(change.reviewers.*, change.owner)',
      ],

      detached: function() {
        this._clearInputRequestHandle();
      },

      _clearInputRequestHandle: function() {
        if (this._inputRequestHandle != null) {
          this.cancelAsync(this._inputRequestHandle);
          this._inputRequestHandle = null;
        }
      },

      _reviewersChanged: function(changeRecord, owner) {
        var result = [];
        var reviewers = changeRecord.base;
        for (var key in reviewers) {
          if (key == 'REVIEWER' || key == 'CC') {
            result = result.concat(reviewers[key]);
          }
        }
        this._reviewers = result.filter(function(reviewer) {
          return reviewer._account_id != owner._account_id;
        });
      },

      _computeCannotRemoveReviewer: function(reviewer, mutable) {
        if (!mutable) { return true; }

        for (var i = 0; i < this.change.removable_reviewers.length; i++) {
          if (this.change.removable_reviewers[i]._account_id ==
              reviewer._account_id) {
            return false;
          }
        }
        return true;
      },

      _computeAutocompleteURL: function(change) {
        return '/changes/' + change._number + '/suggest_reviewers';
      },

      _computeAutocompleteParams: function(inputVal) {
        return {
          n: 10,  // Return max 10 results
          q: inputVal,
        };
      },

      _computeSelected: function(index, selectedIndex) {
        return index == selectedIndex;
      },

      _handleResponse: function(e) {
        this._autocompleteData = e.detail.response.filter(function(reviewer) {
          var account = reviewer.account;
          if (!account) { return true; }
          for (var i = 0; i < this._reviewers.length; i++) {
            if (account._account_id == this.change.owner._account_id ||
                account._account_id == this._reviewers[i]._account_id) {
              return false;
            }
          }
          return true;
        }, this);
      },

      _handleBodyClick: function(e) {
        var eventPath = Polymer.dom(e).path;
        for (var i = 0; i < eventPath.length; i++) {
          if (eventPath[i] == this) {
            return;
          }
        }
        this._selectedIndex = -1;
        this._autocompleteData = [];
      },

      _handleRemoveTap: function(e) {
        e.preventDefault();
        var target = Polymer.dom(e).rootTarget;
        var accountID = parseInt(target.getAttribute('data-account-id'), 10);
        this._send('DELETE', this._restEndpoint(accountID)).then(function(req) {
          var reviewers = this.change.reviewers;
          ['REVIEWER', 'CC'].forEach(function(type) {
            reviewers[type] = reviewers[type] || [];
            for (var i = 0; i < reviewers[type].length; i++) {
              if (reviewers[type][i]._account_id == accountID) {
                this.splice('change.reviewers.' + type, i, 1);
                break;
              }
            }
          }, this);
        }.bind(this)).catch(function(err) {
          alert('Oops. Something went wrong. Check the console and bug the ' +
              'PolyGerrit team for assistance.');
          throw err;
        }.bind(this));
      },

      _handleAddTap: function(e) {
        e.preventDefault();
        this._showInput = true;
        this.$.input.focus();
      },

      _handleCancelTap: function(e) {
        e.preventDefault();
        this._cancel();
      },

      _handleMouseEnterItem: function(e) {
        this._selectedIndex =
            parseInt(Polymer.dom(e).rootTarget.getAttribute('data-index'), 10);
      },

      _handleItemTap: function(e) {
        var reviewerEl;
        var eventPath = Polymer.dom(e).path;
        for (var i = 0; i < eventPath.length; i++) {
          var el = eventPath[i];
          if (el.classList && el.classList.contains('reviewer')) {
            reviewerEl = el;
            break;
          }
        }
        this._selectedIndex =
            parseInt(reviewerEl.getAttribute('data-index'), 10);
        this._sendAddRequest();
      },

      _autocompleteDataChanged: function(data) {
        this._hideAutocomplete = data.length == 0;
      },

      _hideAutocompleteChanged: function(hidden) {
        if (hidden) {
          document.body.removeEventListener('click',
              this._boundBodyClickHandler);
          this._selectedIndex = -1;
        } else {
          document.body.addEventListener('click', this._boundBodyClickHandler);
          this._selectedIndex = 0;
        }
      },

      _inputValChanged: function(val) {
        var sendRequest = function() {
          if (this.disabled || val == null || val.trim().length == 0) {
            return;
          }
          if (val.length < this.suggestFrom) {
            this._clearInputRequestHandle();
            this._hideAutocomplete = true;
            this._selectedIndex = -1;
            return;
          }
          this._lastAutocompleteRequest =
              this.$.autocompleteXHR.generateRequest();
        }.bind(this);

        this._clearInputRequestHandle();
        if (this._inputRequestTimeout == 0) {
          sendRequest();
        } else {
          this._inputRequestHandle =
              this.async(sendRequest, this._inputRequestTimeout);
        }
      },

      _handleKey: function(e) {
        if (this._hideAutocomplete) {
          if (e.keyCode == 27) {  // 'esc'
            e.preventDefault();
            this._cancel();
          }
          return;
        }

        switch (e.keyCode) {
          case 38:  // 'up':
            e.preventDefault();
            this._selectedIndex = Math.max(this._selectedIndex - 1, 0);
            break;
          case 40:  // 'down'
            e.preventDefault();
            this._selectedIndex = Math.min(this._selectedIndex + 1,
                                           this._autocompleteData.length - 1);
            break;
          case 27:  // 'esc'
            e.preventDefault();
            this._hideAutocomplete = true;
            break;
          case 13:  // 'enter'
            e.preventDefault();
            this._sendAddRequest();
            break;
        }
      },

      _cancel: function() {
        this._showInput = false;
        this._selectedIndex = 0;
        this._inputVal = '';
        this._autocompleteData = [];
        this.$.addReviewer.focus();
      },

      _sendAddRequest: function() {
        this._clearInputRequestHandle();

        var reviewerID;
        var reviewer = this._autocompleteData[this._selectedIndex];
        if (reviewer.account) {
          reviewerID = reviewer.account._account_id;
        } else if (reviewer.group) {
          reviewerID = reviewer.group.id;
        }
        this._autocompleteData = [];
        this._send('POST', this._restEndpoint(), reviewerID).then(function(req) {
          this.change.reviewers.CC = this.change.reviewers.CC || [];
          req.response.reviewers.forEach(function(r) {
            this.push('change.removable_reviewers', r);
            this.push('change.reviewers.CC', r);
          }, this);
          this._inputVal = '';
          this.$.input.focus();
        }.bind(this)).catch(function(err) {
          // TODO(andybons): Use the message returned by the server.
          alert('Unable to add ' + reviewerID + ' as a reviewer.');
          throw err;
        }.bind(this));
      },

      _send: function(method, url, reviewerID) {
        this.disabled = true;
        var request = document.createElement('gr-request');
        var opts = {
          method: method,
          url: url,
        };
        if (reviewerID) {
          opts.body = {reviewer: reviewerID};
        }
        this._xhrPromise = request.send(opts);
        var enableEl = function() { this.disabled = false; }.bind(this);
        this._xhrPromise.then(enableEl).catch(enableEl);
        return this._xhrPromise;
      },

      _restEndpoint: function(id) {
        var path = '/changes/' + this.change._number + '/reviewers';
        if (id) {
          path += '/' + id;
        }
        return path;
      },
    });
  })();
  </script>
</dom-module>
