// 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(window, GrDiffGroup, GrDiffLine) {
  'use strict';

  function GrDiffBuilder(diff, comments, prefs, outputEl) {
    this._comments = comments;
    this._prefs = prefs;
    this._outputEl = outputEl;
    this._groups = [];

    this._commentLocations = this._getCommentLocations(comments);
    this._processContent(diff.content, this._groups, prefs.context);
  }

  GrDiffBuilder.LESS_THAN_CODE = '<'.charCodeAt(0);
  GrDiffBuilder.GREATER_THAN_CODE = '>'.charCodeAt(0);
  GrDiffBuilder.AMPERSAND_CODE = '&'.charCodeAt(0);
  GrDiffBuilder.SEMICOLON_CODE = ';'.charCodeAt(0);

  GrDiffBuilder.TAB_REGEX = /\t/g;

  GrDiffBuilder.LINE_FEED_HTML =
      '<span class="style-scope gr-diff br"></span>';

  GrDiffBuilder.GroupType = {
    ADDED: 'b',
    BOTH: 'ab',
    REMOVED: 'a',
  };

  GrDiffBuilder.Highlights = {
    ADDED: 'edit_b',
    REMOVED: 'edit_a',
  };

  GrDiffBuilder.Side = {
    LEFT: 'left',
    RIGHT: 'right',
  };

  GrDiffBuilder.prototype.emitDiff = function() {
    for (var i = 0; i < this._groups.length; i++) {
      this.emitGroup(this._groups[i]);
    }
  };

  GrDiffBuilder.prototype.emitGroup = function(group, opt_beforeSection) {
    throw Error('Subclasses must implement emitGroup');
  };

  GrDiffBuilder.prototype._processContent = function(content, groups, context) {
    this._appendFileComments(groups);

    var WHOLE_FILE = -1;
    context = content.length > 1 ? context : WHOLE_FILE;

    var lineNums = {
      left: 0,
      right: 0,
    };
    content = this._splitCommonGroupsWithComments(content, lineNums);
    for (var i = 0; i < content.length; i++) {
      var group = content[i];
      var lines = [];

      if (group[GrDiffBuilder.GroupType.BOTH] !== undefined) {
        var rows = group[GrDiffBuilder.GroupType.BOTH];
        this._appendCommonLines(rows, lines, lineNums);

        var hiddenRange = [context, rows.length - context];
        if (i === 0) {
          hiddenRange[0] = 0;
        } else if (i === content.length - 1) {
          hiddenRange[1] = rows.length;
        }

        if (context !== WHOLE_FILE && hiddenRange[1] - hiddenRange[0] > 0) {
          this._insertContextGroups(groups, lines, hiddenRange);
        } else {
          groups.push(new GrDiffGroup(GrDiffGroup.Type.BOTH, lines));
        }
        continue;
      }

      if (group[GrDiffBuilder.GroupType.REMOVED] !== undefined) {
        var highlights = undefined;
        if (group[GrDiffBuilder.Highlights.REMOVED] !== undefined) {
          highlights = this._normalizeIntralineHighlights(
              group[GrDiffBuilder.GroupType.REMOVED],
              group[GrDiffBuilder.Highlights.REMOVED]);
        }
        this._appendRemovedLines(group[GrDiffBuilder.GroupType.REMOVED], lines,
            lineNums, highlights);
      }

      if (group[GrDiffBuilder.GroupType.ADDED] !== undefined) {
        var highlights = undefined;
        if (group[GrDiffBuilder.Highlights.ADDED] !== undefined) {
          highlights = this._normalizeIntralineHighlights(
            group[GrDiffBuilder.GroupType.ADDED],
            group[GrDiffBuilder.Highlights.ADDED]);
        }
        this._appendAddedLines(group[GrDiffBuilder.GroupType.ADDED], lines,
            lineNums, highlights);
      }
      groups.push(new GrDiffGroup(GrDiffGroup.Type.DELTA, lines));
    }
  };

  GrDiffBuilder.prototype._appendFileComments = function(groups) {
    var line = new GrDiffLine(GrDiffLine.Type.BOTH);
    line.beforeNumber = GrDiffLine.FILE;
    line.afterNumber = GrDiffLine.FILE;
    groups.push(new GrDiffGroup(GrDiffGroup.Type.BOTH, [line]));
  };

  GrDiffBuilder.prototype._getCommentLocations = function(comments) {
    var result = {
      left: {},
      right: {},
    };
    for (var side in comments) {
      if (side !== GrDiffBuilder.Side.LEFT &&
          side !== GrDiffBuilder.Side.RIGHT) {
        continue;
      }
      comments[side].forEach(function(c) {
        result[side][c.line || GrDiffLine.FILE] = true;
      });
    }
    return result;
  };

  GrDiffBuilder.prototype._commentIsAtLineNum = function(side, lineNum) {
    return this._commentLocations[side][lineNum] === true;
  };

  // In order to show comments out of the bounds of the selected context,
  // treat them as separate chunks within the model so that the content (and
  // context surrounding it) renders correctly.
  GrDiffBuilder.prototype._splitCommonGroupsWithComments = function(content,
      lineNums) {
    var result = [];
    var leftLineNum = lineNums.left;
    var rightLineNum = lineNums.right;
    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._commentIsAtLineNum(GrDiffBuilder.Side.LEFT, leftLineNum) ||
            this._commentIsAtLineNum(GrDiffBuilder.Side.RIGHT, rightLineNum)) {
          if (currentChunk.ab && currentChunk.ab.length > 0) {
            result.push(currentChunk);
            currentChunk = {ab: []};
          }
          result.push({ab: [chunk[j]]});
        } else {
          currentChunk.ab.push(chunk[j]);
        }
      }
      if (currentChunk.ab != null && currentChunk.ab.length > 0) {
        result.push(currentChunk);
      }
    }
    return result;
  };

  // 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.
  GrDiffBuilder.prototype._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;
  };

  GrDiffBuilder.prototype._insertContextGroups = function(groups, lines,
      hiddenRange) {
    var linesBeforeCtx = lines.slice(0, hiddenRange[0]);
    var hiddenLines = lines.slice(hiddenRange[0], hiddenRange[1]);
    var linesAfterCtx = lines.slice(hiddenRange[1]);

    if (linesBeforeCtx.length > 0) {
      groups.push(new GrDiffGroup(GrDiffGroup.Type.BOTH, linesBeforeCtx));
    }

    var ctxLine = new GrDiffLine(GrDiffLine.Type.CONTEXT_CONTROL);
    ctxLine.contextLines = hiddenLines;
    groups.push(new GrDiffGroup(GrDiffGroup.Type.CONTEXT_CONTROL,
        [ctxLine]));

    if (linesAfterCtx.length > 0) {
      groups.push(new GrDiffGroup(GrDiffGroup.Type.BOTH, linesAfterCtx));
    }
  };

  GrDiffBuilder.prototype._appendCommonLines = function(rows, lines, lineNums) {
    for (var i = 0; i < rows.length; i++) {
      var line = new GrDiffLine(GrDiffLine.Type.BOTH);
      line.text = rows[i];
      line.beforeNumber = ++lineNums.left;
      line.afterNumber = ++lineNums.right;
      lines.push(line);
    }
  };

  GrDiffBuilder.prototype._appendRemovedLines = function(rows, lines, lineNums,
      opt_highlights) {
    for (var i = 0; i < rows.length; i++) {
      var line = new GrDiffLine(GrDiffLine.Type.REMOVE);
      line.text = rows[i];
      line.beforeNumber = ++lineNums.left;
      if (opt_highlights) {
        line.highlights = opt_highlights.filter(function(hl) {
          return hl.contentIndex === i;
        });
      }
      lines.push(line);
    }
  };

  GrDiffBuilder.prototype._appendAddedLines = function(rows, lines, lineNums,
      opt_highlights) {
    for (var i = 0; i < rows.length; i++) {
      var line = new GrDiffLine(GrDiffLine.Type.ADD);
      line.text = rows[i];
      line.afterNumber = ++lineNums.right;
      if (opt_highlights) {
        line.highlights = opt_highlights.filter(function(hl) {
          return hl.contentIndex === i;
        });
      }
      lines.push(line);
    }
  };

  GrDiffBuilder.prototype._createContextControl = function(section, line) {
    if (!line.contextLines.length) {
      return null;
    }
    var td = this._createElement('td');
    var button = this._createElement('gr-button', 'showContext');
    button.setAttribute('link', true);
    var commonLines = line.contextLines.length;
    var text = 'Show ' + commonLines + ' common line';
    if (commonLines > 1) {
      text += 's';
    }
    text += '...';
    button.textContent = text;
    button.addEventListener('tap', function(e) {
      e.detail = {
        group: new GrDiffGroup(GrDiffGroup.Type.BOTH, line.contextLines),
        section: section,
      };
      // Let it bubble up the DOM tree.
    });
    td.appendChild(button);
    return td;
  };

  GrDiffBuilder.prototype._getCommentsForLine = function(comments, line,
      opt_side) {
    function byLineNum(lineNum) {
      return function(c) {
        return (c.line === lineNum) ||
               (c.line === undefined && lineNum === GrDiffLine.FILE);
      };
    }
    var leftComments =
        comments[GrDiffBuilder.Side.LEFT].filter(byLineNum(line.beforeNumber));
    var rightComments =
        comments[GrDiffBuilder.Side.RIGHT].filter(byLineNum(line.afterNumber));

    var result;

    switch (opt_side) {
      case GrDiffBuilder.Side.LEFT:
        result = leftComments;
        break;
      case GrDiffBuilder.Side.RIGHT:
        result = rightComments;
        break;
      default:
        result = leftComments.concat(rightComments);
        break;
    }

    return result;
  };

  GrDiffBuilder.prototype.createCommentThread = function(changeNum, patchNum,
      path, side, projectConfig) {
    var threadEl = document.createElement('gr-diff-comment-thread');
    threadEl.changeNum = changeNum;
    threadEl.patchNum = patchNum;
    threadEl.path = path;
    threadEl.side = side;
    threadEl.projectConfig = projectConfig;
    return threadEl;
  };

  GrDiffBuilder.prototype._commentThreadForLine = function(line, opt_side) {
    var comments = this._getCommentsForLine(this._comments, line, opt_side);
    if (!comments || comments.length === 0) {
      return null;
    }

    var patchNum = this._comments.meta.patchRange.patchNum;
    var side = 'REVISION';
    if (line.type === GrDiffLine.Type.REMOVE ||
        opt_side === GrDiffBuilder.Side.LEFT) {
      if (this._comments.meta.patchRange.basePatchNum === 'PARENT') {
        side = 'PARENT';
      } else {
        patchNum = this._comments.meta.patchRange.basePatchNum;
      }
    }
    var threadEl = this.createCommentThread(
        this._comments.meta.changeNum,
        patchNum,
        this._comments.meta.path,
        side,
        this._comments.meta.projectConfig);
    threadEl.comments = comments;
    return threadEl;
  };

  GrDiffBuilder.prototype._createLineEl = function(line, number, type,
      opt_class) {
    var td = this._createElement('td');
    if (opt_class) {
      td.classList.add(opt_class);
    }
    if (line.type === GrDiffLine.Type.BLANK) {
      return td;
    } else if (line.type === GrDiffLine.Type.CONTEXT_CONTROL) {
      td.classList.add('contextLineNum');
      td.setAttribute('data-value', '@@');
    } else if (line.type === GrDiffLine.Type.BOTH || line.type == type) {
      td.classList.add('lineNum');
      td.setAttribute('data-value', number);
    }
    return td;
  };

  GrDiffBuilder.prototype._createTextEl = function(line) {
    var td = this._createElement('td');
    if (line.type !== GrDiffLine.Type.BLANK) {
      td.classList.add('content');
    }
    td.classList.add(line.type);
    var text = line.text;
    var html = util.escapeHTML(text);

    td.classList.add(line.highlights.length > 0 ?
        'lightHighlight' : 'darkHighlight');

    if (line.highlights.length > 0) {
      html = this._addIntralineHighlights(text, html, line.highlights);
    }

    if (this._textLength(text, this._prefs.tab_size) >
        this._prefs.line_length) {
      html = this._addNewlines(text, html);
    }
    html = this._addTabWrappers(html);

    // If the html is equivalent to the text then it didn't get highlighted
    // or escaped. Use textContent which is faster than innerHTML.
    if (html === text) {
      td.textContent = text;
    } else {
      td.innerHTML = html;
    }
    return td;
  };

  GrDiffBuilder.prototype._textLength = function(text, tabSize) {
    // TODO(andybons): Unicode support.
    var numChars = 0;
    for (var i = 0; i < text.length; i++) {
      if (text[i] === '\t') {
        numChars += tabSize;
      } else {
        numChars++;
      }
    }
    return numChars;
  };

  // Advance `index` by the appropriate number of characters that would
  // represent one source code character and return that index. For
  // example, for source code '<span>' the escaped html string is
  // '&lt;span&gt;'. Advancing from index 0 on the prior html string would
  // return 4, since &lt; maps to one source code character ('<').
  GrDiffBuilder.prototype._advanceChar = function(html, index) {
    // TODO(andybons): Unicode is all kinds of messed up in JS. Account for it.
    // https://mathiasbynens.be/notes/javascript-unicode

    // Tags don't count as characters
    while (index < html.length &&
           html.charCodeAt(index) == GrDiffBuilder.LESS_THAN_CODE) {
      while (index < html.length &&
             html.charCodeAt(index) != GrDiffBuilder.GREATER_THAN_CODE) {
        index++;
      }
      index++;  // skip the ">" itself
    }
    // An HTML entity (e.g., &lt;) counts as one character.
    if (index < html.length &&
        html.charCodeAt(index) == GrDiffBuilder.AMPERSAND_CODE) {
      while (index < html.length &&
             html.charCodeAt(index) != GrDiffBuilder.SEMICOLON_CODE) {
        index++;
      }
    }
    return index + 1;
  };

  GrDiffBuilder.prototype._addNewlines = function(text, html) {
    var htmlIndex = 0;
    var indices = [];
    var numChars = 0;
    for (var i = 0; i < text.length; i++) {
      if (numChars > 0 && numChars % this._prefs.line_length === 0) {
        indices.push(htmlIndex);
      }
      htmlIndex = this._advanceChar(html, htmlIndex);
      if (text[i] === '\t') {
        numChars += this._prefs.tab_size;
      } else {
        numChars++;
      }
    }
    var result = html;
    // Since the result string is being altered in place, start from the end
    // of the string so that the insertion indices are not affected as the
    // result string changes.
    for (var i = indices.length - 1; i >= 0; i--) {
      result = result.slice(0, indices[i]) + GrDiffBuilder.LINE_FEED_HTML +
          result.slice(indices[i]);
    }
    return result;
  };

  GrDiffBuilder.prototype._addTabWrappers = function(html) {
    var htmlStr = this._getTabWrapper(this._prefs.tab_size,
        this._prefs.show_tabs);
    return html.replace(GrDiffBuilder.TAB_REGEX, htmlStr);
  };

  GrDiffBuilder.prototype._addIntralineHighlights = function(content, html,
      highlights) {
    var START_TAG = '<hl class="style-scope gr-diff">';
    var END_TAG = '</hl>';

    for (var i = 0; i < highlights.length; i++) {
      var hl = highlights[i];

      var htmlStartIndex = 0;
      // Find the index of the HTML string to insert the start tag.
      for (var j = 0; j < hl.startIndex; j++) {
        htmlStartIndex = this._advanceChar(html, htmlStartIndex);
      }

      var htmlEndIndex = 0;
      if (hl.endIndex !== undefined) {
        for (var j = 0; j < hl.endIndex; j++) {
          htmlEndIndex = this._advanceChar(html, htmlEndIndex);
        }
      } else {
        // If endIndex isn't present, continue to the end of the line.
        htmlEndIndex = html.length;
      }
      // The start and end indices could be the same if a highlight is meant
      // to start at the end of a line and continue onto the next one.
      // Ignore it.
      if (htmlStartIndex !== htmlEndIndex) {
        html = html.slice(0, htmlStartIndex) + START_TAG +
              html.slice(htmlStartIndex, htmlEndIndex) + END_TAG +
              html.slice(htmlEndIndex);
      }
    }
    return html;
  };

  GrDiffBuilder.prototype._getTabWrapper = function(tabSize, showTabs) {
    // Force this to be a number to prevent arbitrary injection.
    tabSize = +tabSize;
    if (isNaN(tabSize)) {
      throw Error('Invalid tab size from preferences.');
    }

    var str = '<span class="style-scope gr-diff tab ';
    if (showTabs) {
      str += 'withIndicator';
    }
    str += '" style="';
    // TODO(andybons): CSS tab-size is not supported in IE.
    str += 'tab-size:' + tabSize + ';';
    str += '-moz-tab-size:' + tabSize + ';';
    str += '">\t</span>';
    return str;
  };

  GrDiffBuilder.prototype._createElement = function(tagName, className) {
    var el = document.createElement(tagName);
    // When Shady DOM is being used, these classes are added to account for
    // Polymer's polyfill behavior. In order to guarantee sufficient
    // specificity within the CSS rules, these are added to every element.
    // Since the Polymer DOM utility functions (which would do this
    // automatically) are not being used for performance reasons, this is
    // done manually.
    el.classList.add('style-scope', 'gr-diff');
    if (!!className) {
      el.classList.add(className);
    }
    return el;
  };

  window.GrDiffBuilder = GrDiffBuilder;
})(window, GrDiffGroup, GrDiffLine);
