/**
 * @license
 * Copyright (C) 2018 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';

  const MSG_EMPTY_BLAME = 'No blame information for this diff.';

  const EVENT_AGAINST_PARENT = 'diff-against-parent';
  const EVENT_ZERO_REBASE = 'rebase-percent-zero';
  const EVENT_NONZERO_REBASE = 'rebase-percent-nonzero';

  const DiffViewMode = {
    SIDE_BY_SIDE: 'SIDE_BY_SIDE',
    UNIFIED: 'UNIFIED_DIFF',
  };

  /** @enum {string} */
  const TimingLabel = {
    TOTAL: 'Diff Total Render',
    CONTENT: 'Diff Content Render',
    SYNTAX: 'Diff Syntax Render',
  };

  const WHITESPACE_IGNORE_NONE = 'IGNORE_NONE';

  /**
   * @param {Object} diff
   * @return {boolean}
   */
  function isImageDiff(diff) {
    if (!diff) { return false; }

    const isA = diff.meta_a &&
        diff.meta_a.content_type.startsWith('image/');
    const isB = diff.meta_b &&
        diff.meta_b.content_type.startsWith('image/');

    return !!(diff.binary && (isA || isB));
  }

  /** @enum {string} */
  Gerrit.DiffSide = {
    LEFT: 'left',
    RIGHT: 'right',
  };

  /**
   * Wrapper around gr-diff.
   *
   * Webcomponent fetching diffs and related data from restAPI and passing them
   * to the presentational gr-diff for rendering.
   */
  Polymer({
    is: 'gr-diff-host',
    _legacyUndefinedCheck: true,

    /**
     * Fired when the user selects a line.
     * @event line-selected
     */

    /**
     * Fired if being logged in is required.
     *
     * @event show-auth-required
     */

    /**
     * Fired when a comment is saved or discarded
     *
     * @event diff-comments-modified
     */

    properties: {
      changeNum: String,
      noAutoRender: {
        type: Boolean,
        value: false,
      },
      /** @type {?} */
      patchRange: Object,
      path: String,
      prefs: {
        type: Object,
      },
      projectName: String,
      displayLine: {
        type: Boolean,
        value: false,
      },
      isImageDiff: {
        type: Boolean,
        computed: '_computeIsImageDiff(_diff)',
        notify: true,
      },
      commitRange: Object,
      filesWeblinks: {
        type: Object,
        value() {
          return {};
        },
        notify: true,
      },
      hidden: {
        type: Boolean,
        reflectToAttribute: true,
      },
      noRenderOnPrefsChange: {
        type: Boolean,
        value: false,
      },
      comments: {
        type: Object,
        observer: '_commentsChanged',
      },
      lineWrapping: {
        type: Boolean,
        value: false,
      },
      viewMode: {
        type: String,
        value: DiffViewMode.SIDE_BY_SIDE,
      },

      /**
       * Special line number which should not be collapsed into a shared region.
       * @type {{
       *  number: number,
       *  leftSide: {boolean}
       * }|null}
       */
      lineOfInterest: Object,

      /**
       * If the diff fails to load, show the failure message in the diff rather
       * than bubbling the error up to the whole page. This is useful for when
       * loading inline diffs because one diff failing need not mark the whole
       * page with a failure.
       */
      showLoadFailure: Boolean,

      isBlameLoaded: {
        type: Boolean,
        notify: true,
        computed: '_computeIsBlameLoaded(_blame)',
      },

      _loggedIn: {
        type: Boolean,
        value: false,
      },

      _loading: {
        type: Boolean,
        value: false,
      },

      /** @type {?string} */
      _errorMessage: {
        type: String,
        value: null,
      },

      /** @type {?Object} */
      _baseImage: Object,
      /** @type {?Object} */
      _revisionImage: Object,

      _diff: Object,

      /** @type {?Object} */
      _blame: {
        type: Object,
        value: null,
      },

      /**
       * TODO(brohlfs): Replace Object type by Gerrit.CoverageRange.
       *
       * @type {!Array<!Object>}
       */
      _coverageRanges: {
        type: Array,
        value: () => [],
      },

      _loadedWhitespaceLevel: String,

      _parentIndex: {
        type: Number,
        computed: '_computeParentIndex(patchRange.*)',
      },
    },

    behaviors: [
      Gerrit.FireBehavior,
      Gerrit.PatchSetBehavior,
    ],

    listeners: {
      // These are named inconsistently for a reason:
      // The create-comment event is fired to indicate that we should
      // create a comment.
      // The comment-* events are just notifying that the comments did already
      // change in some way, and that we should update any models we may want
      // to keep in sync.
      'create-comment': '_handleCreateComment',
      'comment-discard': '_handleCommentDiscard',
      'comment-update': '_handleCommentUpdate',
      'comment-save': '_handleCommentSave',

      'render-start': '_handleRenderStart',
      'render-content': '_handleRenderContent',
      'render-syntax': '_handleRenderSyntax',

      'normalize-range': '_handleNormalizeRange',
    },

    observers: [
      '_whitespaceChanged(prefs.ignore_whitespace, _loadedWhitespaceLevel,' +
          ' noRenderOnPrefsChange)',
    ],

    ready() {
      if (this._canReload()) {
        this.reload();
      }
    },

    attached() {
      this._getLoggedIn().then(loggedIn => {
        this._loggedIn = loggedIn;
      });
    },

    /** @return {!Promise} */
    reload() {
      this._loading = true;
      this._errorMessage = null;
      const whitespaceLevel = this._getIgnoreWhitespace();

      this._coverageRanges = [];
      const {changeNum, path, patchRange: {basePatchNum, patchNum}} = this;
      this.$.jsAPI.getCoverageRanges(changeNum, path, basePatchNum, patchNum).
          then(coverageRanges => {
            if (changeNum !== this.changeNum ||
                path !== this.path ||
                basePatchNum !== this.patchRange.basePatchNum ||
                patchNum !== this.patchRange.patchNum) {
              return;
            }
            this._coverageRanges = coverageRanges;
          }).catch(err => {
            console.warn('Loading coverage ranges failed: ', err);
          });

      const diffRequest = this._getDiff()
          .then(diff => {
            this._loadedWhitespaceLevel = whitespaceLevel;
            this._reportDiff(diff);
            return diff;
          })
          .catch(e => {
            this._handleGetDiffError(e);
            return null;
          });

      const assetRequest = diffRequest.then(diff => {
        // If the diff is null, then it's failed to load.
        if (!diff) { return null; }

        return this._loadDiffAssets(diff);
      });

      return Promise.all([diffRequest, assetRequest])
          .then(results => {
            const diff = results[0];
            if (!diff) {
              return Promise.resolve();
            }
            this.filesWeblinks = this._getFilesWeblinks(diff);
            return new Promise(resolve => {
              const callback = () => {
                resolve();
                this.removeEventListener('render', callback);
              };
              this.addEventListener('render', callback);
              this._diff = diff;
            });
          })
          .catch(err => {
            console.warn('Error encountered loading diff:', err);
          })
          .then(() => { this._loading = false; });
    },

    _getFilesWeblinks(diff) {
      if (!this.commitRange) {
        return {};
      }
      return {
        meta_a: Gerrit.Nav.getFileWebLinks(
            this.projectName, this.commitRange.baseCommit, this.path,
            {weblinks: diff && diff.meta_a && diff.meta_a.web_links}),
        meta_b: Gerrit.Nav.getFileWebLinks(
            this.projectName, this.commitRange.commit, this.path,
            {weblinks: diff && diff.meta_b && diff.meta_b.web_links}),
      };
    },

    /** Cancel any remaining diff builder rendering work. */
    cancel() {
      this.$.diff.cancel();
    },

    /** @return {!Array<!HTMLElement>} */
    getCursorStops() {
      return this.$.diff.getCursorStops();
    },

    /** @return {boolean} */
    isRangeSelected() {
      return this.$.diff.isRangeSelected();
    },

    toggleLeftDiff() {
      this.$.diff.toggleLeftDiff();
    },

    /**
     * Load and display blame information for the base of the diff.
     * @return {Promise} A promise that resolves when blame finishes rendering.
     */
    loadBlame() {
      return this.$.restAPI.getBlame(this.changeNum, this.patchRange.patchNum,
          this.path, true)
          .then(blame => {
            if (!blame.length) {
              this.fire('show-alert', {message: MSG_EMPTY_BLAME});
              return Promise.reject(MSG_EMPTY_BLAME);
            }

            this._blame = blame;
          });
    },

    /** Unload blame information for the diff. */
    clearBlame() {
      this._blame = null;
    },

    /**
     * The thread elements in this diff, in no particular order.
     * @return {!Array<!HTMLElement>}
     */
    getThreadEls() {
      // Polymer2: querySelectorAll returns NodeList instead of Array.
      return Array.from(
          Polymer.dom(this.$.diff).querySelectorAll('.comment-thread'));
    },

    /** @param {HTMLElement} el */
    addDraftAtLine(el) {
      this.$.diff.addDraftAtLine(el);
    },

    clearDiffContent() {
      this.$.diff.clearDiffContent();
    },

    expandAllContext() {
      this.$.diff.expandAllContext();
    },

    /** @return {!Promise} */
    _getLoggedIn() {
      return this.$.restAPI.getLoggedIn();
    },

    /** @return {boolean}} */
    _canReload() {
      return !!this.changeNum && !!this.patchRange && !!this.path &&
          !this.noAutoRender;
    },

    /** @return {!Promise<!Object>} */
    _getDiff() {
      // Wrap the diff request in a new promise so that the error handler
      // rejects the promise, allowing the error to be handled in the .catch.
      return new Promise((resolve, reject) => {
        this.$.restAPI.getDiff(
            this.changeNum,
            this.patchRange.basePatchNum,
            this.patchRange.patchNum,
            this.path,
            this._getIgnoreWhitespace(),
            reject)
            .then(resolve);
      });
    },

    _handleGetDiffError(response) {
      // Loading the diff may respond with 409 if the file is too large. In this
      // case, use a toast error..
      if (response.status === 409) {
        this.fire('server-error', {response});
        return;
      }

      if (this.showLoadFailure) {
        this._errorMessage = [
          'Encountered error when loading the diff:',
          response.status,
          response.statusText,
        ].join(' ');
        return;
      }

      this.fire('page-error', {response});
    },

    /**
     * Report info about the diff response.
     */
    _reportDiff(diff) {
      if (!diff || !diff.content) {
        return;
      }

      // Count the delta lines stemming from normal deltas, and from
      // due_to_rebase deltas.
      let nonRebaseDelta = 0;
      let rebaseDelta = 0;
      diff.content.forEach(chunk => {
        if (chunk.ab) { return; }
        const deltaSize = Math.max(
            chunk.a ? chunk.a.length : 0, chunk.b ? chunk.b.length : 0);
        if (chunk.due_to_rebase) {
          rebaseDelta += deltaSize;
        } else {
          nonRebaseDelta += deltaSize;
        }
      });

      // Find the percent of the delta from due_to_rebase chunks rounded to two
      // digits. Diffs with no delta are considered 0%.
      const totalDelta = rebaseDelta + nonRebaseDelta;
      const percentRebaseDelta = !totalDelta ? 0 :
          Math.round(100 * rebaseDelta / totalDelta);

      // Report the due_to_rebase percentage in the "diff" category when
      // applicable.
      if (this.patchRange.basePatchNum === 'PARENT') {
        this.$.reporting.reportInteraction(EVENT_AGAINST_PARENT);
      } else if (percentRebaseDelta === 0) {
        this.$.reporting.reportInteraction(EVENT_ZERO_REBASE);
      } else {
        this.$.reporting.reportInteraction(EVENT_NONZERO_REBASE,
            percentRebaseDelta);
      }
    },

    /**
     * @param {Object} diff
     * @return {!Promise}
     */
    _loadDiffAssets(diff) {
      if (isImageDiff(diff)) {
        return this._getImages(diff).then(images => {
          this._baseImage = images.baseImage;
          this._revisionImage = images.revisionImage;
        });
      } else {
        this._baseImage = null;
        this._revisionImage = null;
        return Promise.resolve();
      }
    },

    /**
     * @param {Object} diff
     * @return {boolean}
     */
    _computeIsImageDiff(diff) {
      return isImageDiff(diff);
    },

    _commentsChanged(newComments) {
      const allComments = [];
      for (const side of [GrDiffBuilder.Side.LEFT, GrDiffBuilder.Side.RIGHT]) {
        // This is needed by the threading.
        for (const comment of newComments[side]) {
          comment.__commentSide = side;
        }
        allComments.push(...newComments[side]);
      }
      // Currently, the only way this is ever changed here is when the initial
      // comments are loaded, so it's okay performance wise to clear the threads
      // and recreate them. If this changes in future, we might want to reuse
      // some DOM nodes here.
      this._clearThreads();
      const threads = this._createThreads(allComments);
      for (const thread of threads) {
        const threadEl = this._createThreadElement(thread);
        this._attachThreadElement(threadEl);
      }
    },

    /**
     * @param {!Array<!Object>} comments
     * @return {!Array<!Object>} Threads for the given comments.
     */
    _createThreads(comments) {
      const sortedComments = comments.slice(0).sort((a, b) => {
        if (b.__draft && !a.__draft ) { return 0; }
        if (a.__draft && !b.__draft ) { return 1; }
        return util.parseDate(a.updated) - util.parseDate(b.updated);
      });

      const threads = [];
      for (const comment of sortedComments) {
        // If the comment is in reply to another comment, find that comment's
        // thread and append to it.
        if (comment.in_reply_to) {
          const thread = threads.find(thread =>
              thread.comments.some(c => c.id === comment.in_reply_to));
          if (thread) {
            thread.comments.push(comment);
            continue;
          }
        }

        // Otherwise, this comment starts its own thread.
        const newThread = {
          start_datetime: comment.updated,
          comments: [comment],
          commentSide: comment.__commentSide,
          patchNum: comment.patch_set,
          rootId: comment.id || comment.__draftID,
          lineNum: comment.line,
          isOnParent: comment.side === 'PARENT',
        };
        if (comment.range) {
          newThread.range = Object.assign({}, comment.range);
        }
        threads.push(newThread);
      }
      return threads;
    },

    /**
     * @param {Object} blame
     * @return {boolean}
     */
    _computeIsBlameLoaded(blame) {
      return !!blame;
    },

    /**
     * @param {Object} diff
     * @return {!Promise}
     */
    _getImages(diff) {
      return this.$.restAPI.getImagesForDiff(this.changeNum, diff,
          this.patchRange);
    },

    /** @param {CustomEvent} e */
    _handleCreateComment(e) {
      const {lineNum, side, patchNum, isOnParent, range} = e.detail;
      const threadEl = this._getOrCreateThread(patchNum, lineNum, side, range,
          isOnParent);
      threadEl.addOrEditDraft(lineNum, range);

      this.$.reporting.recordDraftInteraction();
    },

    /**
     * Gets or creates a comment thread at a given location.
     * May provide a range, to get/create a range comment.
     *
     * @param {string} patchNum
     * @param {?number} lineNum
     * @param {string} commentSide
     * @param {Gerrit.Range|undefined} range
     * @param {boolean} isOnParent
     * @return {!Object}
     */
    _getOrCreateThread(patchNum, lineNum, commentSide, range, isOnParent) {
      let threadEl = this._getThreadEl(lineNum, commentSide, range);
      if (!threadEl) {
        threadEl = this._createThreadElement({
          comments: [],
          commentSide,
          patchNum,
          lineNum,
          range,
          isOnParent,
        });
        this._attachThreadElement(threadEl);
      }
      return threadEl;
    },

    _attachThreadElement(threadEl) {
      Polymer.dom(this.$.diff).appendChild(threadEl);
    },

    _clearThreads() {
      for (const threadEl of this.getThreadEls()) {
        const parent = Polymer.dom(threadEl).parentNode;
        Polymer.dom(parent).removeChild(threadEl);
      }
    },

    _createThreadElement(thread) {
      const threadEl = document.createElement('gr-comment-thread');
      threadEl.className = 'comment-thread';
      threadEl.setAttribute('slot', `${thread.commentSide}-${thread.lineNum}`);
      threadEl.comments = thread.comments;
      threadEl.commentSide = thread.commentSide;
      threadEl.isOnParent = !!thread.isOnParent;
      threadEl.parentIndex = this._parentIndex;
      threadEl.changeNum = this.changeNum;
      threadEl.patchNum = thread.patchNum;
      threadEl.lineNum = thread.lineNum;
      const rootIdChangedListener = changeEvent => {
        thread.rootId = changeEvent.detail.value;
      };
      threadEl.addEventListener('root-id-changed', rootIdChangedListener);
      threadEl.path = this.path;
      threadEl.projectName = this.projectName;
      threadEl.range = thread.range;
      const threadDiscardListener = e => {
        const threadEl = /** @type {!Node} */ (e.currentTarget);

        const parent = Polymer.dom(threadEl).parentNode;
        Polymer.dom(parent).removeChild(threadEl);

        threadEl.removeEventListener('root-id-changed', rootIdChangedListener);
        threadEl.removeEventListener('thread-discard', threadDiscardListener);
      };
      threadEl.addEventListener('thread-discard', threadDiscardListener);
      return threadEl;
    },

    /**
     * Gets a comment thread element at a given location.
     * May provide a range, to get a range comment.
     *
     * @param {?number} lineNum
     * @param {string} commentSide
     * @param {!Gerrit.Range=} range
     * @return {?Node}
     */
    _getThreadEl(lineNum, commentSide, range = undefined) {
      let line;
      if (commentSide === GrDiffBuilder.Side.LEFT) {
        line = {beforeNumber: lineNum};
      } else if (commentSide === GrDiffBuilder.Side.RIGHT) {
        line = {afterNumber: lineNum};
      } else {
        throw new Error(`Unknown side: ${commentSide}`);
      }
      function matchesRange(threadEl) {
        const threadRange = /** @type {!Gerrit.Range} */(
            JSON.parse(threadEl.getAttribute('range')));
        return Gerrit.rangesEqual(threadRange, range);
      }

      const filteredThreadEls = this._filterThreadElsForLocation(
          this.getThreadEls(), line, commentSide).filter(matchesRange);
      return filteredThreadEls.length ? filteredThreadEls[0] : null;
    },

    /**
     * @param {!Array<!HTMLElement>} threadEls
     * @param {!{beforeNumber: (number|string|undefined|null),
     *           afterNumber: (number|string|undefined|null)}}
     *     lineInfo
     * @param {!Gerrit.DiffSide=} side The side (LEFT, RIGHT) for
     *     which to return the threads.
     * @return {!Array<!HTMLElement>} The thread elements matching the given
     *     location.
     */
    _filterThreadElsForLocation(threadEls, lineInfo, side) {
      function matchesLeftLine(threadEl) {
        return threadEl.getAttribute('comment-side') ==
            Gerrit.DiffSide.LEFT &&
            threadEl.getAttribute('line-num') == lineInfo.beforeNumber;
      }
      function matchesRightLine(threadEl) {
        return threadEl.getAttribute('comment-side') ==
            Gerrit.DiffSide.RIGHT &&
            threadEl.getAttribute('line-num') == lineInfo.afterNumber;
      }
      function matchesFileComment(threadEl) {
        return threadEl.getAttribute('comment-side') == side &&
              // line/range comments have 1-based line set, if line is falsy it's
              // a file comment
              !threadEl.getAttribute('line-num');
      }

      // Select the appropriate matchers for the desired side and line
      // If side is BOTH, we want both the left and right matcher.
      const matchers = [];
      if (side !== Gerrit.DiffSide.RIGHT) {
        matchers.push(matchesLeftLine);
      }
      if (side !== Gerrit.DiffSide.LEFT) {
        matchers.push(matchesRightLine);
      }
      if (lineInfo.afterNumber === 'FILE' ||
          lineInfo.beforeNumber === 'FILE') {
        matchers.push(matchesFileComment);
      }
      return threadEls.filter(threadEl =>
          matchers.some(matcher => matcher(threadEl)));
    },

    _getIgnoreWhitespace() {
      if (!this.prefs || !this.prefs.ignore_whitespace) {
        return WHITESPACE_IGNORE_NONE;
      }
      return this.prefs.ignore_whitespace;
    },

    _whitespaceChanged(
        preferredWhitespaceLevel, loadedWhitespaceLevel,
        noRenderOnPrefsChange) {
      // Polymer 2: check for undefined
      if ([
        preferredWhitespaceLevel,
        loadedWhitespaceLevel,
        noRenderOnPrefsChange,
      ].some(arg => arg === undefined)) {
        return;
      }

      if (preferredWhitespaceLevel !== loadedWhitespaceLevel &&
          !noRenderOnPrefsChange) {
        this.reload();
      }
    },

    /**
     * @param {Object} patchRangeRecord
     * @return {number|null}
     */
    _computeParentIndex(patchRangeRecord) {
      return this.isMergeParent(patchRangeRecord.base.basePatchNum) ?
          this.getParentIndex(patchRangeRecord.base.basePatchNum) : null;
    },

    _handleCommentSave(e) {
      const comment = e.detail.comment;
      const side = e.detail.comment.__commentSide;
      const idx = this._findDraftIndex(comment, side);
      this.set(['comments', side, idx], comment);
      this._handleCommentSaveOrDiscard();
    },

    _handleCommentDiscard(e) {
      const comment = e.detail.comment;
      this._removeComment(comment);
      this._handleCommentSaveOrDiscard();
    },

    /**
     * Closure annotation for Polymer.prototype.push is off. Submitted PR:
     * https://github.com/Polymer/polymer/pull/4776
     * but for not supressing annotations.
     *
     * @suppress {checkTypes}
     */
    _handleCommentUpdate(e) {
      const comment = e.detail.comment;
      const side = e.detail.comment.__commentSide;
      let idx = this._findCommentIndex(comment, side);
      if (idx === -1) {
        idx = this._findDraftIndex(comment, side);
      }
      if (idx !== -1) { // Update draft or comment.
        this.set(['comments', side, idx], comment);
      } else { // Create new draft.
        this.push(['comments', side], comment);
      }
    },

    _handleCommentSaveOrDiscard() {
      this.dispatchEvent(new CustomEvent(
          'diff-comments-modified', {bubbles: true, composed: true}));
    },

    _removeComment(comment) {
      const side = comment.__commentSide;
      this._removeCommentFromSide(comment, side);
    },

    _removeCommentFromSide(comment, side) {
      let idx = this._findCommentIndex(comment, side);
      if (idx === -1) {
        idx = this._findDraftIndex(comment, side);
      }
      if (idx !== -1) {
        this.splice('comments.' + side, idx, 1);
      }
    },

    /** @return {number} */
    _findCommentIndex(comment, side) {
      if (!comment.id || !this.comments[side]) {
        return -1;
      }
      return this.comments[side].findIndex(item => item.id === comment.id);
    },

    /** @return {number} */
    _findDraftIndex(comment, side) {
      if (!comment.__draftID || !this.comments[side]) {
        return -1;
      }
      return this.comments[side].findIndex(
          item => item.__draftID === comment.__draftID);
    },

    _handleRenderStart() {
      this.$.reporting.time(TimingLabel.TOTAL);
      this.$.reporting.time(TimingLabel.CONTENT);
    },

    _handleRenderContent() {
      this.$.reporting.timeEnd(TimingLabel.CONTENT);
      this.$.reporting.time(TimingLabel.SYNTAX);
    },

    _handleRenderSyntax() {
      this.$.reporting.timeEnd(TimingLabel.SYNTAX);
      this.$.reporting.timeEnd(TimingLabel.TOTAL);
    },

    _handleNormalizeRange(event) {
      this.$.reporting.reportInteraction('normalize-range',
          `Modified invalid comment range on l. ${event.detail.lineNum}` +
          ` of the ${event.detail.side} side`);
    },
  });
})();
