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

  const Defs = {};

  /**
   * @typedef {{
   *    basePatchNum: (string|number),
   *    patchNum: (number),
   * }}
   */
  Defs.patchRange;

  /**
   * @typedef {{
   *    changeNum: number,
   *    path: string,
   *    patchRange: !Defs.patchRange,
   *    projectConfig: (Object|undefined),
   * }}
   */
  Defs.commentMeta;

  /**
   * @typedef {{
   *    meta: !Defs.commentMeta,
   *    left: !Array,
   *    right: !Array,
   * }}
   */
  Defs.commentsBySide;

  /**
   * Construct a change comments object, which can be data-bound to child
   * elements of that which uses the gr-comment-api.
   *
   * @param {!Object} comments
   * @param {!Object} robotComments
   * @param {!Object} drafts
   * @param {number} changeNum
   * @constructor
   */
  function ChangeComments(comments, robotComments, drafts, changeNum) {
    this._comments = comments;
    this._robotComments = robotComments;
    this._drafts = drafts;
    this._changeNum = changeNum;
  }

  ChangeComments.prototype = {
    get comments() {
      return this._comments;
    },
    get drafts() {
      return this._drafts;
    },
    get robotComments() {
      return this._robotComments;
    },
  };

  ChangeComments.prototype._patchNumEquals =
      Gerrit.PatchSetBehavior.patchNumEquals;
  ChangeComments.prototype._isMergeParent =
      Gerrit.PatchSetBehavior.isMergeParent;
  ChangeComments.prototype._getParentIndex =
      Gerrit.PatchSetBehavior.getParentIndex;

  /**
   * Get an object mapping file paths to a boolean representing whether that
   * path contains diff comments in the given patch set (including drafts and
   * robot comments).
   *
   * Paths with comments are mapped to true, whereas paths without comments
   * are not mapped.
   *
   * @param {Defs.patchRange=} opt_patchRange The patch-range object containing
   *     patchNum and basePatchNum properties to represent the range.
   * @return {!Object}
   */
  ChangeComments.prototype.getPaths = function(opt_patchRange) {
    const responses = [this.comments, this.drafts, this.robotComments];
    const commentMap = {};
    for (const response of responses) {
      for (const path in response) {
        if (response.hasOwnProperty(path) &&
            response[path].some(c => {
              // If don't care about patch range, we know that the path exists.
              if (!opt_patchRange) { return true; }
              return this._isInPatchRange(c, opt_patchRange);
            })) {
          commentMap[path] = true;
        }
      }
    }
    return commentMap;
  };

  /**
   * Gets all the comments and robot comments for the given change.
   *
   * @param {number=} opt_patchNum
   * @return {!Object}
   */
  ChangeComments.prototype.getAllPublishedComments = function(opt_patchNum) {
    return this.getAllComments(false, opt_patchNum);
  };

  /**
   * Gets all the comments for a particular thread group. Used for refreshing
   * comments after the thread group has already been built.
   *
   * @param {string} rootId
   * @return {!Array} an array of comments
   */
  ChangeComments.prototype.getCommentsForThread = function(rootId) {
    const allThreads = this.getAllThreadsForChange();
    const threadMatch = allThreads.find(t => t.rootId === rootId);

    // In the event that a single draft comment was removed by the thread-list
    // and the diff view is updating comments, there will no longer be a thread
    // found.  In this case, return null.
    return threadMatch ? threadMatch.comments : null;
  };

  /**
   * Filters an array of comments by line and side
   *
   * @param {!Array} comments
   * @param {boolean} parentOnly whether the only comments returned should have
   *   the side attribute set to PARENT
   * @param {string} commentSide whether the comment was left on the left or the
   *   right side regardless or unified or side-by-side
   * @param {number=} opt_line line number, can be undefined if file comment
   * @return {!Array} an array of comments
   */
  ChangeComments.prototype._filterCommentsBySideAndLine = function(comments,
      parentOnly, commentSide, opt_line) {
    return comments.filter(c => {
      // if parentOnly, only match comments with PARENT for the side.
      let sideMatch = parentOnly ? c.side === PARENT : c.side !== PARENT;
      if (parentOnly) {
        sideMatch = sideMatch && c.side === PARENT;
      }
      return sideMatch && c.line === opt_line;
    }).map(c => {
      c.__commentSide = commentSide;
      return c;
    });
  };

  /**
   * Gets all the comments and robot comments for the given change.
   *
   * @param {boolean=} opt_includeDrafts
   * @param {number=} opt_patchNum
   * @return {!Object}
   */
  ChangeComments.prototype.getAllComments = function(opt_includeDrafts,
      opt_patchNum) {
    const paths = this.getPaths();
    const publishedComments = {};
    for (const path of Object.keys(paths)) {
      let commentsToAdd = this.getAllCommentsForPath(path, opt_patchNum);
      if (opt_includeDrafts) {
        const drafts = this.getAllDraftsForPath(path, opt_patchNum)
            .map(d => Object.assign({__draft: true}, d));
        commentsToAdd = commentsToAdd.concat(drafts);
      }
      publishedComments[path] = commentsToAdd;
    }
    return publishedComments;
  };

  /**
   * Gets all the comments and robot comments for the given change.
   *
   * @param {number=} opt_patchNum
   * @return {!Object}
   */
  ChangeComments.prototype.getAllDrafts = function(opt_patchNum) {
    const paths = this.getPaths();
    const drafts = {};
    for (const path of Object.keys(paths)) {
      drafts[path] = this.getAllDraftsForPath(path, opt_patchNum);
    }
    return drafts;
  };

  /**
   * Get the comments (robot comments) for a path and optional patch num.
   *
   * @param {!string} path
   * @param {number=} opt_patchNum
   * @param {boolean=} opt_includeDrafts
   * @return {!Array}
   */
  ChangeComments.prototype.getAllCommentsForPath = function(path,
      opt_patchNum, opt_includeDrafts) {
    const comments = this._comments[path] || [];
    const robotComments = this._robotComments[path] || [];
    let allComments = comments.concat(robotComments);
    if (opt_includeDrafts) {
      const drafts = this.getAllDraftsForPath(path)
          .map(d => Object.assign({__draft: true}, d));
      allComments = allComments.concat(drafts);
    }
    if (!opt_patchNum) { return allComments; }
    return (allComments || []).filter(c =>
      this._patchNumEquals(c.patch_set, opt_patchNum)
    );
  };

  /**
   * Get the drafts for a path and optional patch num.
   *
   * @param {!string} path
   * @param {number=} opt_patchNum
   * @return {!Array}
   */
  ChangeComments.prototype.getAllDraftsForPath = function(path,
      opt_patchNum) {
    const comments = this._drafts[path] || [];
    if (!opt_patchNum) { return comments; }
    return (comments || []).filter(c =>
      this._patchNumEquals(c.patch_set, opt_patchNum)
    );
  };

  /**
   * Get the comments (with drafts and robot comments) for a path and
   * patch-range. Returns an object with left and right properties mapping to
   * arrays of comments in on either side of the patch range for that path.
   *
   * @param {!string} path
   * @param {!Defs.patchRange} patchRange The patch-range object containing patchNum
   *     and basePatchNum properties to represent the range.
   * @param {Object=} opt_projectConfig Optional project config object to
   *     include in the meta sub-object.
   * @return {!Defs.commentsBySide}
   */
  ChangeComments.prototype.getCommentsBySideForPath = function(path,
      patchRange, opt_projectConfig) {
    const comments = this.comments[path] || [];
    const drafts = this.drafts[path] || [];
    const robotComments = this.robotComments[path] || [];

    drafts.forEach(d => { d.__draft = true; });

    const all = comments.concat(drafts).concat(robotComments);

    const baseComments = all.filter(c =>
      this._isInBaseOfPatchRange(c, patchRange));
    const revisionComments = all.filter(c =>
      this._isInRevisionOfPatchRange(c, patchRange));

    return {
      meta: {
        changeNum: this._changeNum,
        path,
        patchRange,
        projectConfig: opt_projectConfig,
      },
      left: baseComments,
      right: revisionComments,
    };
  };

  /**
   * @param {!Object} comments Object keyed by file, with a value of an array
   *   of comments left on that file.
   * @return {!Array} A flattened list of all comments, where each comment
   *   also includes the file that it was left on, which was the key of the
   *   originall object.
   */
  ChangeComments.prototype._commentObjToArrayWithFile = function(comments) {
    let commentArr = [];
    for (const file of Object.keys(comments)) {
      const commentsForFile = [];
      for (const comment of comments[file]) {
        commentsForFile.push(Object.assign({__path: file}, comment));
      }
      commentArr = commentArr.concat(commentsForFile);
    }
    return commentArr;
  };

  ChangeComments.prototype._commentObjToArray = function(comments) {
    let commentArr = [];
    for (const file of Object.keys(comments)) {
      commentArr = commentArr.concat(comments[file]);
    }
    return commentArr;
  };

  /**
   * Computes a string counting the number of commens in a given file and path.
   *
   * @param {number} patchNum
   * @param {string=} opt_path
   * @return {number}
   */
  ChangeComments.prototype.computeCommentCount = function(patchNum, opt_path) {
    if (opt_path) {
      return this.getAllCommentsForPath(opt_path, patchNum).length;
    }
    const allComments = this.getAllPublishedComments(patchNum);
    return this._commentObjToArray(allComments).length;
  };

  /**
   * Computes a string counting the number of draft comments in the entire
   * change, optionally filtered by path and/or patchNum.
   *
   * @param {number=} opt_patchNum
   * @param {string=} opt_path
   * @return {number}
   */
  ChangeComments.prototype.computeDraftCount = function(opt_patchNum,
      opt_path) {
    if (opt_path) {
      return this.getAllDraftsForPath(opt_path, opt_patchNum).length;
    }
    const allDrafts = this.getAllDrafts(opt_patchNum);
    return this._commentObjToArray(allDrafts).length;
  };

  /**
   * Computes a number of unresolved comment threads in a given file and path.
   *
   * @param {number} patchNum
   * @param {string=} opt_path
   * @return {number}
   */
  ChangeComments.prototype.computeUnresolvedNum = function(patchNum,
      opt_path) {
    let comments = [];
    let drafts = [];

    if (opt_path) {
      comments = this.getAllCommentsForPath(opt_path, patchNum);
      drafts = this.getAllDraftsForPath(opt_path, patchNum);
    } else {
      comments = this._commentObjToArray(
          this.getAllPublishedComments(patchNum));
    }

    comments = comments.concat(drafts);

    const threads = this.getCommentThreads(this._sortComments(comments));

    const unresolvedThreads = threads
        .filter(thread =>
          thread.comments.length &&
          thread.comments[thread.comments.length - 1].unresolved);

    return unresolvedThreads.length;
  };

  ChangeComments.prototype.getAllThreadsForChange = function() {
    const comments = this._commentObjToArrayWithFile(this.getAllComments(true));
    const sortedComments = this._sortComments(comments);
    return this.getCommentThreads(sortedComments);
  };

  ChangeComments.prototype._sortComments = function(comments) {
    return comments.slice(0).sort((c1, c2) => {
      return util.parseDate(c1.updated) - util.parseDate(c2.updated);
    });
  };

  /**
   * Computes all of the comments in thread format.
   *
   * @param {!Array} comments sorted by updated timestamp.
   * @return {!Array}
   */
  ChangeComments.prototype.getCommentThreads = function(comments) {
    const threads = [];
    const idThreadMap = {};
    for (const comment of comments) {
      // 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 = idThreadMap[comment.in_reply_to];
        if (thread) {
          thread.comments.push(comment);
          idThreadMap[comment.id] = thread;
          continue;
        }
      }

      // Otherwise, this comment starts its own thread.
      const newThread = {
        comments: [comment],
        patchNum: comment.patch_set,
        path: comment.__path,
        line: comment.line,
        rootId: comment.id,
      };
      if (comment.side) {
        newThread.commentSide = comment.side;
      }
      threads.push(newThread);
      idThreadMap[comment.id] = newThread;
    }
    return threads;
  };

  /**
   * Whether the given comment should be included in the base side of the
   * given patch range.
   *
   * @param {!Object} comment
   * @param {!Defs.patchRange} range
   * @return {boolean}
   */
  ChangeComments.prototype._isInBaseOfPatchRange = function(comment, range) {
    // If the base of the patch range is a parent of a merge, and the comment
    // appears on a specific parent then only show the comment if the parent
    // index of the comment matches that of the range.
    if (comment.parent && comment.side === PARENT) {
      return this._isMergeParent(range.basePatchNum) &&
          comment.parent === this._getParentIndex(range.basePatchNum);
    }

    // If the base of the range is the parent of the patch:
    if (range.basePatchNum === PARENT &&
        comment.side === PARENT &&
        this._patchNumEquals(comment.patch_set, range.patchNum)) {
      return true;
    }
    // If the base of the range is not the parent of the patch:
    if (range.basePatchNum !== PARENT &&
        comment.side !== PARENT &&
        this._patchNumEquals(comment.patch_set, range.basePatchNum)) {
      return true;
    }
    return false;
  };

  /**
   * Whether the given comment should be included in the revision side of the
   * given patch range.
   *
   * @param {!Object} comment
   * @param {!Defs.patchRange} range
   * @return {boolean}
   */
  ChangeComments.prototype._isInRevisionOfPatchRange = function(comment,
      range) {
    return comment.side !== PARENT &&
        this._patchNumEquals(comment.patch_set, range.patchNum);
  };

  /**
   * Whether the given comment should be included in the given patch range.
   *
   * @param {!Object} comment
   * @param {!Defs.patchRange} range
   * @return {boolean|undefined}
   */
  ChangeComments.prototype._isInPatchRange = function(comment, range) {
    return this._isInBaseOfPatchRange(comment, range) ||
        this._isInRevisionOfPatchRange(comment, range);
  };

  Polymer({
    is: 'gr-comment-api',

    properties: {
      _changeComments: Object,
    },

    listeners: {
      'reload-drafts': 'reloadDrafts',
    },

    behaviors: [
      Gerrit.PatchSetBehavior,
    ],

    /**
     * Load all comments (with drafts and robot comments) for the given change
     * number. The returned promise resolves when the comments have loaded, but
     * does not yield the comment data.
     *
     * @param {number} changeNum
     * @return {!Promise<!Object>}
     */
    loadAll(changeNum) {
      const promises = [];
      promises.push(this.$.restAPI.getDiffComments(changeNum));
      promises.push(this.$.restAPI.getDiffRobotComments(changeNum));
      promises.push(this.$.restAPI.getDiffDrafts(changeNum));

      return Promise.all(promises).then(([comments, robotComments, drafts]) => {
        this._changeComments = new ChangeComments(comments,
            robotComments, drafts, changeNum);
        return this._changeComments;
      });
    },

    /**
     * Re-initialize _changeComments with a new ChangeComments object, that
     * uses the previous values for comments and robot comments, but fetches
     * updated draft comments.
     *
     * @param {number} changeNum
     * @return {!Promise<!Object>}
     */
    reloadDrafts(changeNum) {
      if (!this._changeComments) {
        return this.loadAll(changeNum);
      }
      return this.$.restAPI.getDiffDrafts(changeNum).then(drafts => {
        this._changeComments = new ChangeComments(this._changeComments.comments,
            this._changeComments.robotComments, drafts, changeNum);
        return this._changeComments;
      });
    },
  });
})();
