// 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';

  var COMMIT_MESSAGE_PATH = '/COMMIT_MSG';

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

    properties: {
      patchRange: Object,
      patchNum: String,
      changeNum: String,
      comments: Object,
      drafts: Object,
      revisions: Object,
      projectConfig: Object,
      selectedIndex: {
        type: Number,
        notify: true,
      },
      keyEventTarget: {
        type: Object,
        value: function() { return document.body; },
      },
      change: Object,

      _files: {
        type: Array,
        observer: '_filesChanged',
        value: function() { return []; },
      },
      _loggedIn: {
        type: Boolean,
        value: false,
      },
      _reviewed: {
        type: Array,
        value: function() { return []; },
      },
      _diffPrefs: Object,
      _userPrefs: Object,
      _localPrefs: Object,
      _showInlineDiffs: Boolean,
      _numFilesShown: {
        type: Number,
        value: 75,
      },
      _fileListIncrement: {
        type: Number,
        readOnly: true,
        value: 75,
      },
      _shownFiles: {
        type: Array,
        computed: '_computeFilesShown(_numFilesShown, _files.*)',
      },
    },

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

    reload: function() {
      if (!this.changeNum || !this.patchRange.patchNum) {
        return Promise.resolve();
      }
      this._collapseAllDiffs();
      var promises = [];
      var _this = this;

      promises.push(this._getFiles().then(function(files) {
        _this._files = files;
      }));
      promises.push(this._getLoggedIn().then(function(loggedIn) {
        return _this._loggedIn = loggedIn;
      }).then(function(loggedIn) {
        if (!loggedIn) { return; }

        return _this._getReviewedFiles().then(function(reviewed) {
          _this._reviewed = reviewed;
        });
      }));

      this._localPrefs = this.$.storage.getPreferences();
      promises.push(this._getDiffPreferences().then(function(prefs) {
        this._diffPrefs = prefs;
      }.bind(this)));

      promises.push(this._getPreferences().then(function(prefs) {
        this._userPrefs = prefs;
      }.bind(this)));
    },

    get diffs() {
      return Polymer.dom(this.root).querySelectorAll('gr-diff');
    },

    _getDiffPreferences: function() {
      return this.$.restAPI.getDiffPreferences();
    },

    _getPreferences: function() {
      return this.$.restAPI.getPreferences();
    },

    _computePatchSets: function(revisions) {
      var patchNums = [];
      for (var commit in revisions) {
        patchNums.push(revisions[commit]._number);
      }
      return patchNums.sort(function(a, b) { return a - b; });
    },

    _computePatchSetDisabled: function(patchNum, currentPatchNum) {
      return parseInt(patchNum, 10) >= parseInt(currentPatchNum, 10);
    },

    _computePatchSetSelected: function(patchNum, basePatchNum) {
      return parseInt(patchNum, 10) === parseInt(basePatchNum, 10);
    },

    _handleHiddenChange: function(e) {
      var model = e.model;
      model.set('file.__expanded', !model.file.__expanded);
    },

    _handlePatchChange: function(e) {
      var patchRange = Object.assign({}, this.patchRange);
      patchRange.basePatchNum = Polymer.dom(e).rootTarget.value;
      page.show(this.encodeURL('/c/' + this.changeNum + '/' +
          this._patchRangeStr(patchRange), true));
    },

    _forEachDiff: function(fn) {
      var diffs = this.diffs;
      for (var i = 0; i < diffs.length; i++) {
        fn(diffs[i]);
      }
    },

    /**
     * Until upgrading to Polymer 2.0, manual management of reflection between
     * _shownFiles and _files is necessary. Performance of linkPaths is very
     * poor.
     */
    _expandAllDiffs: function(e) {
      this._showInlineDiffs = true;
      for (var i = 0; i < this._files.length; i++) {
        if (i < this._shownFiles.length) {
          this.set(['_shownFiles', i, '__expanded'], true);
        }
        this.set(['_files', i, '__expanded'], true);
      }
      if (e && e.target) {
        e.target.blur();
      }
    },

    _collapseAllDiffs: function(e) {
      this._showInlineDiffs = false;
      for (var i = 0; i < this._files.length; i++) {
        if (i < this._shownFiles.length) {
          this.set(['_shownFiles', i, '__expanded'], false);
        }
        this.set(['_files', i, '__expanded'], false);
      }
      this.$.cursor.handleDiffUpdate();
      if (e && e.target) {
        e.target.blur();
      }
    },

    _computeCommentsString: function(comments, patchNum, path) {
      return this._computeCountString(comments, patchNum, path, 'comment');
    },

    _computeDraftsString: function(drafts, patchNum, path) {
      return this._computeCountString(drafts, patchNum, path, 'draft');
    },

    _computeCountString: function(comments, patchNum, path, noun) {
      if (!comments) { return ''; }

      var patchComments = (comments[path] || []).filter(function(c) {
        return parseInt(c.patch_set, 10) === parseInt(patchNum, 10);
      });
      var num = patchComments.length;
      if (num === 0) { return ''; }
      return num + ' ' + noun + (num > 1 ? 's' : '');
    },

    _computeReviewed: function(file, _reviewed) {
      return _reviewed.indexOf(file.__path) !== -1;
    },

    _handleReviewedChange: function(e) {
      var path = Polymer.dom(e).rootTarget.getAttribute('data-path');
      var index = this._reviewed.indexOf(path);
      var reviewed = index !== -1;
      if (reviewed) {
        this.splice('_reviewed', index, 1);
      } else {
        this.push('_reviewed', path);
      }

      this._saveReviewedState(path, !reviewed).catch(function(err) {
        alert('Couldn’t change file review status. Check the console ' +
            'and contact the PolyGerrit team for assistance.');
        throw err;
      }.bind(this));
    },

    _saveReviewedState: function(path, reviewed) {
      return this.$.restAPI.saveFileReviewed(this.changeNum,
          this.patchRange.patchNum, path, reviewed);
    },

    _getLoggedIn: function() {
      return this.$.restAPI.getLoggedIn();
    },

    _getReviewedFiles: function() {
      return this.$.restAPI.getReviewedFiles(this.changeNum,
          this.patchRange.patchNum);
    },

    _getFiles: function() {
      return this.$.restAPI.getChangeFilesAsSpeciallySortedArray(
          this.changeNum, this.patchRange).then(function(files) {
            // Append UI-specific properties.
            return files.map(function(file) {
              file.__expanded = false;
              return file;
            });
          });
    },

    _handleKey: function(e) {
      if (this.shouldSupressKeyboardShortcut(e)) { return; }
      switch (e.keyCode) {
        case 37: // left
          if (e.shiftKey && this._showInlineDiffs) {
            e.preventDefault();
            this.$.cursor.moveLeft();
          }
          break;
        case 39: // right
          if (e.shiftKey && this._showInlineDiffs) {
            e.preventDefault();
            this.$.cursor.moveRight();
          }
          break;
        case 73:  // 'i'
          if (e.shiftKey) {
            e.preventDefault();
            this._toggleInlineDiffs();
          } else if (this.selectedIndex !== undefined) {
            e.preventDefault();
            var expanded = this._files[this.selectedIndex].__expanded;
            // Until Polymer 2.0, manual management of reflection between _files
            // and _shownFiles is necessary.
            this.set(['_shownFiles', this.selectedIndex, '__expanded'],
                !expanded);
            this.set(['_files', this.selectedIndex, '__expanded'], !expanded);
          }
          break;
        case 40:  // down
        case 74:  // 'j'
          e.preventDefault();
          if (this._showInlineDiffs) {
            this.$.cursor.moveDown();
          } else {
            this.selectedIndex =
                Math.min(this._numFilesShown, this.selectedIndex + 1);
            this._scrollToSelectedFile();
          }
          break;
        case 38:  // up
        case 75:  // 'k'
          e.preventDefault();
          if (this._showInlineDiffs) {
            this.$.cursor.moveUp();
          } else {
            this.selectedIndex = Math.max(0, this.selectedIndex - 1);
            this._scrollToSelectedFile();
          }
          break;
        case 67: // 'c'
          var isRangeSelected = this.diffs.some(function(diff) {
            return diff.isRangeSelected();
          }, this);
          if (this._showInlineDiffs && !isRangeSelected) {
            e.preventDefault();
            this._addDraftAtTarget();
          }
          break;
        case 219:  // '['
          e.preventDefault();
          this._openSelectedFile(this._files.length - 1);
          break;
        case 221:  // ']'
          e.preventDefault();
          this._openSelectedFile(0);
          break;
        case 13:  // <enter>
        case 79:  // 'o'
          e.preventDefault();
          if (this._showInlineDiffs) {
            this._openCursorFile();
          } else {
            this._openSelectedFile();
          }
          break;
        case 78:  // 'n'
          if (this._showInlineDiffs) {
            e.preventDefault();
            if (e.shiftKey) {
              this.$.cursor.moveToNextCommentThread();
            } else {
              this.$.cursor.moveToNextChunk();
            }
          }
          break;
        case 80:  // 'p'
          if (this._showInlineDiffs) {
            e.preventDefault();
            if (e.shiftKey) {
              this.$.cursor.moveToPreviousCommentThread();
            } else {
              this.$.cursor.moveToPreviousChunk();
            }
          }
          break;
        case 65:  // 'a'
          if (e.shiftKey) { // Hide left diff.
            e.preventDefault();
            this._forEachDiff(function(diff) {
              diff.toggleLeftDiff();
            });
          }
          break;
      }
    },

    _toggleInlineDiffs: function() {
      if (this._showInlineDiffs) {
        this._collapseAllDiffs();
      } else {
        this._expandAllDiffs();
      }
    },

    _openCursorFile: function() {
      var diff = this.$.cursor.getTargetDiffElement();
      page.show(this._computeDiffURL(diff.changeNum, diff.patchRange,
          diff.path));
    },

    _openSelectedFile: function(opt_index) {
      if (opt_index != null) {
        this.selectedIndex = opt_index;
      }
      page.show(this._computeDiffURL(this.changeNum, this.patchRange,
          this._files[this.selectedIndex].__path));
    },

    _addDraftAtTarget: function() {
      var diff = this.$.cursor.getTargetDiffElement();
      var target = this.$.cursor.getTargetLineElement();
      if (diff && target) {
        diff.addDraftAtLine(target);
      }
    },

    _scrollToSelectedFile: function() {
      var el = this.$$('.row[selected]');
      var top = 0;
      for (var node = el; node; node = node.offsetParent) {
        top += node.offsetTop;
      }

      // Don't scroll if it's already in view.
      if (top > window.pageYOffset &&
          top < window.pageYOffset + window.innerHeight - el.clientHeight) {
        return;
      }

      window.scrollTo(0, top - document.body.clientHeight / 2);
    },

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

    _computeFileStatus: function(status) {
      return status || 'M';
    },

    _computeDiffURL: function(changeNum, patchRange, path) {
      return this.encodeURL('/c/' + changeNum + '/' +
          this._patchRangeStr(patchRange) + '/' + path, true);
    },

    _patchRangeStr: function(patchRange) {
      return patchRange.basePatchNum !== 'PARENT' ?
          patchRange.basePatchNum + '..' + patchRange.patchNum :
          patchRange.patchNum + '';
    },

    _computeFileDisplayName: function(path) {
      return path === COMMIT_MESSAGE_PATH ? 'Commit message' : path;
    },

    _computeClass: function(baseClass, path) {
      var classes = [baseClass];
      if (path === COMMIT_MESSAGE_PATH) {
        classes.push('invisible');
      }
      return classes.join(' ');
    },

    _computeShowHideText: function(expanded) {
      return expanded ? '▼' : '◀';
    },

    _computeHiddenState: function(expanded) {
      return !expanded;
    },

    _computeFilesShown: function(numFilesShown, files) {
      return files.base.slice(0, numFilesShown);
    },

    _filesChanged: function() {
      this.async(function() {
        var diffElements = Polymer.dom(this.root).querySelectorAll('gr-diff');

        // Overwrite the cursor's list of diffs:
        this.$.cursor.splice.apply(this.$.cursor,
            ['diffs', 0, this.$.cursor.diffs.length].concat(diffElements));
      }.bind(this), 1);
    },

    _incrementNumFilesShown: function() {
      this._numFilesShown += this._fileListIncrement;
    },

    _computeFileListButtonHidden: function(numFilesShown, files) {
      return numFilesShown >= files.length;
    },

    _computeIncrementText: function(numFilesShown, files) {
      if (!files) { return ''; }
      var text =
          Math.min(this._fileListIncrement, files.length - numFilesShown);
      return 'Show ' + text + ' more';
    },

    _computeShowAllText: function(files) {
      if (!files) { return ''; }
      return 'Show all ' + files.length + ' files';
    },

    _showAllFiles: function() {
      this._numFilesShown = this._files.length;
    },
  });
})();
