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

  Polymer({
    is: 'gr-diff-comment-thread-group',

    properties: {
      changeNum: String,
      comments: {
        type: Array,
        value: function() { return []; },
      },
      patchForNewThreads: String,
      projectConfig: Object,
      range: Object,
      side: {
        type: String,
        value: 'REVISION',
      },
      _threads: {
        type: Array,
        value: function() { return []; },
      },
    },

    observers: [
      '_commentsChanged(comments.*)',
    ],

    addNewThread: function(locationRange) {
      this.push('_threads', {
        comments: [],
        locationRange: locationRange,
        patchNum: this.patchForNewThreads,
      });
    },

    removeThread: function(locationRange) {
      for (var i = 0; i < this._threads.length; i++) {
        if (this._threads[i].locationRange === locationRange) {
          this.splice('_threads', i, 1);
          return;
        }
      }
    },

    getThreadForRange: function(rangeToCheck) {
      var threads = [].filter.call(
          Polymer.dom(this.root).querySelectorAll('gr-diff-comment-thread'),
          function(thread) {
            return thread.locationRange === rangeToCheck;
          });
      if (threads.length === 1) {
        return threads[0];
      }
    },

    _commentsChanged: function() {
      this._threads = this._getThreadGroups(this.comments);
    },

    _sortByDate: function(threadGroups) {
      if (!threadGroups.length) { return; }
      return threadGroups.sort(function(a, b) {
        // If a comment is a draft, it doesn't have a start_datetime yet.
        // Assume it is newer than the comment it is being compared to.
        if (!a.start_datetime) {
          return 1;
        }
        if (!b.start_datetime) {
          return -1;
        }
        return util.parseDate(a.start_datetime) -
            util.parseDate(b.start_datetime);
      });
    },

    _calculateLocationRange: function(range, comment) {
      return 'range-' + range.start_line + '-' +
          range.start_character + '-' +
          range.end_line + '-' +
          range.end_character + '-' +
          comment.__commentSide;
    },

    /**
     * Determines what the patchNum of a thread should be. Use patchNum from
     * comment if it exists, otherwise the property of the thread group.
     * This is needed for switching between side-by-side and unified views when
     * there are unsaved drafts.
     */
    _getPatchNum: function(comment) {
      return comment.patchNum || this.patchForNewThreads;
    },

    _getThreadGroups: function(comments) {
      var threadGroups = {};

      comments.forEach(function(comment) {
        var locationRange;
        if (!comment.range) {
          locationRange = 'line-' + comment.__commentSide;
        } else {
          locationRange = this._calculateLocationRange(comment.range, comment);
        }

        if (threadGroups[locationRange]) {
          threadGroups[locationRange].comments.push(comment);
        } else {
          threadGroups[locationRange] = {
            start_datetime: comment.updated,
            comments: [comment],
            locationRange: locationRange,
            commentSide: comment.__commentSide,
            patchNum: this._getPatchNum(comment),
          };
        }
      }.bind(this));

      var threadGroupArr = [];
      var threadGroupKeys = Object.keys(threadGroups);
      threadGroupKeys.forEach(function(threadGroupKey) {
        threadGroupArr.push(threadGroups[threadGroupKey]);
      });

      return this._sortByDate(threadGroupArr);
    },
  });
})();
