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

  Polymer({
    is: 'gr-diff',

    /**
     * Fired when the diff is rendered.
     *
     * @event render
     */

    properties: {
      availablePatches: Array,
      changeNum: String,
      /*
       * A single object to encompass basePatchNum and patchNum is used
       * so that both can be set at once without incremental observers
       * firing after each property changes.
       */
      patchRange: Object,
      path: String,
      prefs: {
        type: Object,
        notify: true,
      },
      projectConfig: Object,

      _prefsReady: {
        type: Object,
        readOnly: true,
        value: function() {
          return new Promise(function(resolve) {
            this._resolvePrefsReady = resolve;
          }.bind(this));
        },
      },
      _baseComments: Array,
      _comments: Array,
      _drafts: Array,
      _baseDrafts: Array,
      /**
       * Base (left side) comments and drafts grouped by line number.
       * Only used for initial rendering.
       */
      _groupedBaseComments: {
        type: Object,
        value: function() { return {}; },
      },
      /**
       * Comments and drafts (right side) grouped by line number.
       * Only used for initial rendering.
       */
      _groupedComments: {
        type: Object,
        value: function() { return {}; },
      },
      _diffResponse: Object,
      _diff: {
        type: Object,
        value: function() { return {}; },
      },
      _loggedIn: {
        type: Boolean,
        value: false,
      },
      _initialRenderComplete: {
        type: Boolean,
        value: false,
      },
      _loading: {
        type: Boolean,
        value: true,
      },
      _savedPrefs: Object,

      _diffPreferencesPromise: Object,  // Used for testing.
    },

    observers: [
      '_prefsChanged(prefs.*)',
    ],

    ready: function() {
      app.accountReady.then(function() {
        this._loggedIn = app.loggedIn;
      }.bind(this));
    },

    scrollToLine: function(lineNum) {
      // TODO(andybons): Should this always be the right side?
      this.$.rightDiff.scrollToLine(lineNum);
    },

    scrollToNextDiffChunk: function() {
      this.$.rightDiff.scrollToNextDiffChunk();
    },

    scrollToPreviousDiffChunk: function() {
      this.$.rightDiff.scrollToPreviousDiffChunk();
    },

    scrollToNextCommentThread: function() {
      this.$.rightDiff.scrollToNextCommentThread();
    },

    scrollToPreviousCommentThread: function() {
      this.$.rightDiff.scrollToPreviousCommentThread();
    },

    reload: function() {
      this._loading = true;
      // If a diff takes a considerable amount of time to render, the previous
      // diff can end up showing up while the DOM is constructed. Clear the
      // content on a reload to prevent this.
      this._diff = {
        leftSide: [],
        rightSide: [],
      };

      var diffLoaded = this._getDiff().then(function(diff) {
        this._diffResponse = diff;
      }.bind(this));

      var promises = [
        this._prefsReady,
        diffLoaded,
      ];

      return app.accountReady.then(function() {
        promises.push(this._getDiffComments().then(function(res) {
          this._baseComments = res.baseComments;
          this._comments = res.comments;
        }.bind(this)));

        if (!app.loggedIn) {
          this._baseDrafts = [];
          this._drafts = [];
        } else {
          promises.push(this._getDiffDrafts().then(function(res) {
            this._baseDrafts = res.baseComments;
            this._drafts = res.comments;
          }.bind(this)));
        }

        return Promise.all(promises).then(function() {
          this._render();
          this._loading = false;
        }.bind(this)).catch(function(err) {
          this._loading = false;
          alert('Oops. Something went wrong. Check the console and bug the ' +
              'PolyGerrit team for assistance.');
          throw err;
        }.bind(this));
      }.bind(this));
    },

    _getDiff: function() {
      return this.$.restAPI.getDiff(
          this.changeNum,
          this.patchRange.basePatchNum,
          this.patchRange.patchNum,
          this.path);
    },

    _getDiffComments: function() {
      return this.$.restAPI.getDiffComments(
          this.changeNum,
          this.patchRange.basePatchNum,
          this.patchRange.patchNum,
          this.path);
    },

    _getDiffDrafts: function() {
      return this.$.restAPI.getDiffDrafts(
          this.changeNum,
          this.patchRange.basePatchNum,
          this.patchRange.patchNum,
          this.path);
    },

    showDiffPreferences: function() {
      this.$.prefsOverlay.open();
    },

    _prefsChanged: function(changeRecord) {
      if (this._initialRenderComplete) {
        this._render();
      }
      this._resolvePrefsReady(changeRecord.base);
    },

    _render: function() {
      this._groupCommentsAndDrafts();
      this._processContent();

      // Allow for the initial rendering to complete before firing the event.
      this.async(function() {
        this.fire('render', null, {bubbles: false});
      }.bind(this), 1);

      this._initialRenderComplete = true;
    },

    _handlePrefsTap: function(e) {
      e.preventDefault();

      // TODO(andybons): This is not supported in IE. Implement a polyfill.
      // NOTE: Object.assign is NOT automatically a deep copy. If prefs adds
      // an object as a value, it must be marked enumerable.
      this._savedPrefs = Object.assign({}, this.prefs);
      this.$.prefsOverlay.open();
    },

    _handlePrefsSave: function(e) {
      e.stopPropagation();
      var el = Polymer.dom(e).rootTarget;
      el.disabled = true;
      app.accountReady.then(function() {
        if (!this._loggedIn) {
          el.disabled = false;
          this.$.prefsOverlay.close();
          return;
        }
        this._saveDiffPreferences().then(function() {
          this.$.prefsOverlay.close();
          el.disabled = false;
        }.bind(this)).catch(function(err) {
          el.disabled = false;
          alert('Oops. Something went wrong. Check the console and bug the ' +
                'PolyGerrit team for assistance.');
          throw err;
        });
      }.bind(this));
    },

    _saveDiffPreferences: function() {
      var xhr = document.createElement('gr-request');
      this._diffPreferencesPromise = xhr.send({
        method: 'PUT',
        url: '/accounts/self/preferences.diff',
        body: this.prefs,
      });
      return this._diffPreferencesPromise;
    },

    _handlePrefsCancel: function(e) {
      e.stopPropagation();
      this.prefs = this._savedPrefs;
      this.$.prefsOverlay.close();
    },

    _handleExpandContext: function(e) {
      var ctx = e.detail.context;
      var contextControlIndex = -1;
      for (var i = ctx.start; i <= ctx.end; i++) {
        this._diff.leftSide[i].hidden = false;
        this._diff.rightSide[i].hidden = false;
        if (this._diff.leftSide[i].type == 'CONTEXT_CONTROL' &&
            this._diff.rightSide[i].type == 'CONTEXT_CONTROL') {
          contextControlIndex = i;
        }
      }
      this._diff.leftSide[contextControlIndex].hidden = true;
      this._diff.rightSide[contextControlIndex].hidden = true;

      this.$.leftDiff.hideElementsWithIndex(contextControlIndex);
      this.$.rightDiff.hideElementsWithIndex(contextControlIndex);

      this.$.leftDiff.renderLineIndexRange(ctx.start, ctx.end);
      this.$.rightDiff.renderLineIndexRange(ctx.start, ctx.end);
    },

    _handleThreadHeightChange: function(e) {
      var index = e.detail.index;
      var diffEl = Polymer.dom(e).rootTarget;
      var otherSide = diffEl == this.$.leftDiff ?
          this.$.rightDiff : this.$.leftDiff;

      var threadHeight = e.detail.height;
      var otherSideHeight;
      if (otherSide.content[index].type == 'COMMENT_THREAD') {
        otherSideHeight = otherSide.getRowNaturalHeight(index);
      } else {
        otherSideHeight = otherSide.getRowHeight(index);
      }
      var maxHeight = Math.max(threadHeight, otherSideHeight);
      this.$.leftDiff.setRowHeight(index, maxHeight);
      this.$.rightDiff.setRowHeight(index, maxHeight);
    },

    _handleAddDraft: function(e) {
      var insertIndex = e.detail.index + 1;
      var diffEl = Polymer.dom(e).rootTarget;
      var content = diffEl.content;
      if (content[insertIndex] &&
          content[insertIndex].type == 'COMMENT_THREAD') {
        // A thread is already here. Do nothing.
        return;
      }
      var comment = {
        type: 'COMMENT_THREAD',
        comments: [{
          __draft: true,
          __draftID: Math.random().toString(36),
          line: e.detail.line,
          path: this.path,
        }]
      };
      if (diffEl == this.$.leftDiff &&
          this.patchRange.basePatchNum == 'PARENT') {
        comment.comments[0].side = 'PARENT';
        comment.patchNum = this.patchRange.patchNum;
      }

      if (content[insertIndex] &&
          content[insertIndex].type == 'FILLER') {
        content[insertIndex] = comment;
        diffEl.rowUpdated(insertIndex);
      } else {
        content.splice(insertIndex, 0, comment);
        diffEl.rowInserted(insertIndex);
      }

      var otherSide = diffEl == this.$.leftDiff ?
          this.$.rightDiff : this.$.leftDiff;
      if (otherSide.content[insertIndex] == null ||
          otherSide.content[insertIndex].type != 'COMMENT_THREAD') {
        otherSide.content.splice(insertIndex, 0, {
          type: 'FILLER',
        });
        otherSide.rowInserted(insertIndex);
      }
    },

    _handleRemoveThread: function(e) {
      var diffEl = Polymer.dom(e).rootTarget;
      var otherSide = diffEl == this.$.leftDiff ?
          this.$.rightDiff : this.$.leftDiff;
      var index = e.detail.index;

      if (otherSide.content[index].type == 'FILLER') {
        otherSide.content.splice(index, 1);
        otherSide.rowRemoved(index);
        diffEl.content.splice(index, 1);
        diffEl.rowRemoved(index);
      } else if (otherSide.content[index].type == 'COMMENT_THREAD') {
        diffEl.content[index] = {type: 'FILLER'};
        diffEl.rowUpdated(index);
        var height = otherSide.setRowNaturalHeight(index);
        diffEl.setRowHeight(index, height);
      } else {
        throw Error('A thread cannot be opposite anything but filler or ' +
            'another thread');
      }
    },

    _processContent: function() {
      var leftSide = [];
      var rightSide = [];
      var initialLineNum = 0 + (this._diffResponse.content.skip || 0);
      var ctx = {
        hidingLines: false,
        lastNumLinesHidden: 0,
        left: {
          lineNum: initialLineNum,
        },
        right: {
          lineNum: initialLineNum,
        }
      };
      var content = this._breakUpCommonChunksWithComments(ctx,
          this._diffResponse.content);
      var context = this.prefs.context;
      if (context == -1) {
        // Show the entire file.
        context = Infinity;
      }
      for (var i = 0; i < content.length; i++) {
        if (i == 0) {
          ctx.skipRange = [0, context];
        } else if (i == content.length - 1) {
          ctx.skipRange = [context, 0];
        } else {
          ctx.skipRange = [context, context];
        }
        ctx.diffChunkIndex = i;
        this._addDiffChunk(ctx, content[i], leftSide, rightSide);
      }

      this._diff = {
        leftSide: leftSide,
        rightSide: rightSide,
      };
    },

    // In order to show comments out of the bounds of the selected context,
    // treat them as diffs within the model so that the content (and context
    // surrounding it) renders correctly.
    _breakUpCommonChunksWithComments: function(ctx, content) {
      var result = [];
      var leftLineNum = ctx.left.lineNum;
      var rightLineNum = ctx.right.lineNum;
      for (var i = 0; i < content.length; i++) {
        if (!content[i].ab) {
          result.push(content[i]);
          if (content[i].a) {
            leftLineNum += content[i].a.length;
          }
          if (content[i].b) {
            rightLineNum += content[i].b.length;
          }
          continue;
        }
        var chunk = content[i].ab;
        var currentChunk = {ab: []};
        for (var j = 0; j < chunk.length; j++) {
          leftLineNum++;
          rightLineNum++;
          if (this._groupedBaseComments[leftLineNum] == null &&
              this._groupedComments[rightLineNum] == null) {
            currentChunk.ab.push(chunk[j]);
          } else {
            if (currentChunk.ab && currentChunk.ab.length > 0) {
              result.push(currentChunk);
              currentChunk = {ab: []};
            }
            // Append an annotation to indicate that this line should not be
            // highlighted even though it's implied with both `a` and `b`
            // defined. This is needed since there may be two lines that
            // should be highlighted but are equal (blank lines, for example).
            result.push({
              __noHighlight: true,
              a: [chunk[j]],
              b: [chunk[j]],
            });
          }
        }
        if (currentChunk.ab != null && currentChunk.ab.length > 0) {
          result.push(currentChunk);
        }
      }
      return result;
    },

    _groupCommentsAndDrafts: function() {
      this._baseDrafts.forEach(function(d) { d.__draft = true; });
      this._drafts.forEach(function(d) { d.__draft = true; });
      var allLeft = this._baseComments.concat(this._baseDrafts);
      var allRight = this._comments.concat(this._drafts);

      var leftByLine = {};
      var rightByLine = {};
      var mapFunc = function(byLine) {
        return function(c) {
          // File comments/drafts are grouped with line 1 for now.
          var line = c.line || 1;
          if (byLine[line] == null) {
            byLine[line] = [];
          }
          byLine[line].push(c);
        };
      };
      allLeft.forEach(mapFunc(leftByLine));
      allRight.forEach(mapFunc(rightByLine));

      this._groupedBaseComments = leftByLine;
      this._groupedComments = rightByLine;
    },

    _addContextControl: function(ctx, leftSide, rightSide) {
      var numLinesHidden = ctx.lastNumLinesHidden;
      var leftStart = leftSide.length - numLinesHidden;
      var leftEnd = leftSide.length;
      var rightStart = rightSide.length - numLinesHidden;
      var rightEnd = rightSide.length;
      if (leftStart != rightStart || leftEnd != rightEnd) {
        throw Error(
            'Left and right ranges for context control should be equal:' +
            'Left: [' + leftStart + ', ' + leftEnd + '] ' +
            'Right: [' + rightStart + ', ' + rightEnd + ']');
      }
      var obj = {
        type: 'CONTEXT_CONTROL',
        numLines: numLinesHidden,
        start: leftStart,
        end: leftEnd,
      };
      // NOTE: Be careful, here. This object is meant to be immutable. If the
      // object is altered within one side's array it will reflect the
      // alterations in another.
      leftSide.push(obj);
      rightSide.push(obj);
    },

    _addCommonDiffChunk: function(ctx, chunk, leftSide, rightSide) {
      for (var i = 0; i < chunk.ab.length; i++) {
        var numLines = Math.ceil(
            this._visibleLineLength(chunk.ab[i]) / this.prefs.line_length);
        var hidden = i >= ctx.skipRange[0] &&
            i < chunk.ab.length - ctx.skipRange[1];
        if (ctx.hidingLines && hidden == false) {
          // No longer hiding lines. Add a context control.
          this._addContextControl(ctx, leftSide, rightSide);
          ctx.lastNumLinesHidden = 0;
        }
        ctx.hidingLines = hidden;
        if (hidden) {
          ctx.lastNumLinesHidden++;
        }

        // Blank lines within a diff content array indicate a newline.
        leftSide.push({
          type: 'CODE',
          hidden: hidden,
          content: chunk.ab[i] || '\n',
          numLines: numLines,
          lineNum: ++ctx.left.lineNum,
        });
        rightSide.push({
          type: 'CODE',
          hidden: hidden,
          content: chunk.ab[i] || '\n',
          numLines: numLines,
          lineNum: ++ctx.right.lineNum,
        });

        this._addCommentsIfPresent(ctx, leftSide, rightSide);
      }
      if (ctx.lastNumLinesHidden > 0) {
        this._addContextControl(ctx, leftSide, rightSide);
      }
    },

    _addDiffChunk: function(ctx, chunk, leftSide, rightSide) {
      if (chunk.ab) {
        this._addCommonDiffChunk(ctx, chunk, leftSide, rightSide);
        return;
      }

      var leftHighlights = [];
      if (chunk.edit_a) {
        leftHighlights =
            this._normalizeIntralineHighlights(chunk.a, chunk.edit_a);
      }
      var rightHighlights = [];
      if (chunk.edit_b) {
        rightHighlights =
            this._normalizeIntralineHighlights(chunk.b, chunk.edit_b);
      }

      var aLen = (chunk.a && chunk.a.length) || 0;
      var bLen = (chunk.b && chunk.b.length) || 0;
      var maxLen = Math.max(aLen, bLen);
      for (var i = 0; i < maxLen; i++) {
        var hasLeftContent = chunk.a && i < chunk.a.length;
        var hasRightContent = chunk.b && i < chunk.b.length;
        var leftContent = hasLeftContent ? chunk.a[i] : '';
        var rightContent = hasRightContent ? chunk.b[i] : '';
        var highlight = !chunk.__noHighlight;
        var maxNumLines = this._maxLinesSpanned(leftContent, rightContent);
        if (hasLeftContent) {
          leftSide.push({
            type: 'CODE',
            content: leftContent || '\n',
            numLines: maxNumLines,
            lineNum: ++ctx.left.lineNum,
            highlight: highlight,
            intraline: highlight && leftHighlights.filter(function(hl) {
              return hl.contentIndex == i;
            }),
          });
        } else {
          leftSide.push({
            type: 'FILLER',
            numLines: maxNumLines,
          });
        }
        if (hasRightContent) {
          rightSide.push({
            type: 'CODE',
            content: rightContent || '\n',
            numLines: maxNumLines,
            lineNum: ++ctx.right.lineNum,
            highlight: highlight,
            intraline: highlight && rightHighlights.filter(function(hl) {
              return hl.contentIndex == i;
            }),
          });
        } else {
          rightSide.push({
            type: 'FILLER',
            numLines: maxNumLines,
          });
        }
        this._addCommentsIfPresent(ctx, leftSide, rightSide);
      }
    },

    _addCommentsIfPresent: function(ctx, leftSide, rightSide) {
      var leftComments = this._groupedBaseComments[ctx.left.lineNum];
      var rightComments = this._groupedComments[ctx.right.lineNum];
      if (leftComments) {
        var thread = {
          type: 'COMMENT_THREAD',
          comments: leftComments,
        };
        if (this.patchRange.basePatchNum == 'PARENT') {
          thread.patchNum = this.patchRange.patchNum;
        }
        leftSide.push(thread);
      }
      if (rightComments) {
        rightSide.push({
          type: 'COMMENT_THREAD',
          comments: rightComments,
        });
      }
      if (leftComments && !rightComments) {
        rightSide.push({type: 'FILLER'});
      } else if (!leftComments && rightComments) {
        leftSide.push({type: 'FILLER'});
      }
      this._groupedBaseComments[ctx.left.lineNum] = null;
      this._groupedComments[ctx.right.lineNum] = null;
    },

    // The `highlights` array consists of a list of <skip length, mark length>
    // pairs, where the skip length is the number of characters between the
    // end of the previous edit and the start of this edit, and the mark
    // length is the number of edited characters following the skip. The start
    // of the edits is from the beginning of the related diff content lines.
    //
    // Note that the implied newline character at the end of each line is
    // included in the length calculation, and thus it is possible for the
    // edits to span newlines.
    //
    // A line highlight object consists of three fields:
    // - contentIndex: The index of the diffChunk `content` field (the line
    //   being referred to).
    // - startIndex: Where the highlight should begin.
    // - endIndex: (optional) Where the highlight should end. If omitted, the
    //   highlight is meant to be a continuation onto the next line.
    _normalizeIntralineHighlights: function(content, highlights) {
      var contentIndex = 0;
      var idx = 0;
      var normalized = [];
      for (var i = 0; i < highlights.length; i++) {
        var line = content[contentIndex] + '\n';
        var hl = highlights[i];
        var j = 0;
        while (j < hl[0]) {
          if (idx == line.length) {
            idx = 0;
            line = content[++contentIndex] + '\n';
            continue;
          }
          idx++;
          j++;
        }
        var lineHighlight = {
          contentIndex: contentIndex,
          startIndex: idx,
        };

        j = 0;
        while (line && j < hl[1]) {
          if (idx == line.length) {
            idx = 0;
            line = content[++contentIndex] + '\n';
            normalized.push(lineHighlight);
            lineHighlight = {
              contentIndex: contentIndex,
              startIndex: idx,
            };
            continue;
          }
          idx++;
          j++;
        }
        lineHighlight.endIndex = idx;
        normalized.push(lineHighlight);
      }
      return normalized;
    },

    _visibleLineLength: function(contents) {
      // http://jsperf.com/performance-of-match-vs-split
      var numTabs = contents.split('\t').length - 1;
      return contents.length - numTabs + (this.prefs.tab_size * numTabs);
    },

    _maxLinesSpanned: function(left, right) {
      return Math.max(
          Math.ceil(this._visibleLineLength(left) / this.prefs.line_length),
          Math.ceil(this._visibleLineLength(right) / this.prefs.line_length));
    },
  });
})();
