/**
 * @license
 * 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';

  /**
   * Possible CSS classes indicating the state of selection. Dynamically added/
   * removed based on where the user clicks within the diff.
   */
  const SelectionClass = {
    COMMENT: 'selected-comment',
    LEFT: 'selected-left',
    RIGHT: 'selected-right',
    BLAME: 'selected-blame',
  };

  const getNewCache = () => { return {left: null, right: null}; };

  Polymer({
    is: 'gr-diff-selection',

    properties: {
      diff: Object,
      /** @type {?Object} */
      _cachedDiffBuilder: Object,
      _linesCache: {
        type: Object,
        value: getNewCache(),
      },
    },

    observers: [
      '_diffChanged(diff)',
    ],

    listeners: {
      copy: '_handleCopy',
      down: '_handleDown',
    },

    behaviors: [
      Gerrit.DomUtilBehavior,
    ],

    attached() {
      this.classList.add(SelectionClass.RIGHT);
    },

    get diffBuilder() {
      if (!this._cachedDiffBuilder) {
        this._cachedDiffBuilder =
            Polymer.dom(this).querySelector('gr-diff-builder');
      }
      return this._cachedDiffBuilder;
    },

    _diffChanged() {
      this._linesCache = getNewCache();
    },

    _handleDown(e) {
      const lineEl = this.diffBuilder.getLineElByChild(e.target);
      const blameSelected = this._elementDescendedFromClass(e.target, 'blame');
      if (!lineEl && !blameSelected) { return; }

      const targetClasses = [];

      if (blameSelected) {
        targetClasses.push(SelectionClass.BLAME);
      } else {
        const commentSelected =
            this._elementDescendedFromClass(e.target, 'gr-diff-comment');
        const side = this.diffBuilder.getSideByLineEl(lineEl);

        targetClasses.push(side === 'left' ?
            SelectionClass.LEFT :
            SelectionClass.RIGHT);

        if (commentSelected) {
          targetClasses.push(SelectionClass.COMMENT);
        }
      }

      this._setClasses(targetClasses);
    },

    /**
     * Set the provided list of classes on the element, to the exclusion of all
     * other SelectionClass values.
     * @param {!Array<!string>} targetClasses
     */
    _setClasses(targetClasses) {
      // Remove any selection classes that do not belong.
      for (const key in SelectionClass) {
        if (SelectionClass.hasOwnProperty(key)) {
          const className = SelectionClass[key];
          if (!targetClasses.includes(className)) {
            this.classList.remove(SelectionClass[key]);
          }
        }
      }
      // Add new selection classes iff they are not already present.
      for (const _class of targetClasses) {
        if (!this.classList.contains(_class)) {
          this.classList.add(_class);
        }
      }
    },

    _getCopyEventTarget(e) {
      return Polymer.dom(e).rootTarget;
    },

    /**
     * Utility function to determine whether an element is a descendant of
     * another element with the particular className.
     *
     * @param {!Element} element
     * @param {!string} className
     * @return {boolean}
     */
    _elementDescendedFromClass(element, className) {
      return this.descendedFromClass(element, className,
          this.diffBuilder.diffElement);
    },

    _handleCopy(e) {
      let commentSelected = false;
      const target = this._getCopyEventTarget(e);
      if (target.type === 'textarea') { return; }
      if (!this._elementDescendedFromClass(target, 'diff-row')) { return; }
      if (this.classList.contains(SelectionClass.COMMENT)) {
        commentSelected = true;
      }
      const lineEl = this.diffBuilder.getLineElByChild(target);
      if (!lineEl) {
        return;
      }
      const side = this.diffBuilder.getSideByLineEl(lineEl);
      const text = this._getSelectedText(side, commentSelected);
      if (text) {
        e.clipboardData.setData('Text', text);
        e.preventDefault();
      }
    },

    /**
     * Get the text of the current window selection. If commentSelected is
     * true, it returns only the text of comments within the selection.
     * Otherwise it returns the text of the selected diff region.
     *
     * @param {!string} side The side that is selected.
     * @param {boolean} commentSelected Whether or not a comment is selected.
     * @return {string} The selected text.
     */
    _getSelectedText(side, commentSelected) {
      const sel = window.getSelection();
      if (sel.rangeCount != 1) {
        return ''; // No multi-select support yet.
      }
      if (commentSelected) {
        return this._getCommentLines(sel, side);
      }
      const range = GrRangeNormalizer.normalize(sel.getRangeAt(0));
      const startLineEl =
          this.diffBuilder.getLineElByChild(range.startContainer);
      const endLineEl = this.diffBuilder.getLineElByChild(range.endContainer);
      const startLineNum = parseInt(startLineEl.getAttribute('data-value'), 10);
      const endLineNum = endLineEl === null ?
          undefined :
          parseInt(endLineEl.getAttribute('data-value'), 10);

      return this._getRangeFromDiff(startLineNum, range.startOffset, endLineNum,
          range.endOffset, side);
    },

    /**
     * Query the diff object for the selected lines.
     *
     * @param {number} startLineNum
     * @param {number} startOffset
     * @param {number|undefined} endLineNum Use undefined to get the range
     *     extending to the end of the file.
     * @param {number} endOffset
     * @param {!string} side The side that is currently selected.
     * @return {string} The selected diff text.
     */
    _getRangeFromDiff(startLineNum, startOffset, endLineNum, endOffset, side) {
      const lines =
          this._getDiffLines(side).slice(startLineNum - 1, endLineNum);
      if (lines.length) {
        lines[lines.length - 1] = lines[lines.length - 1]
            .substring(0, endOffset);
        lines[0] = lines[0].substring(startOffset);
      }
      return lines.join('\n');
    },

    /**
     * Query the diff object for the lines from a particular side.
     *
     * @param {!string} side The side that is currently selected.
     * @return {!Array<string>} An array of strings indexed by line number.
     */
    _getDiffLines(side) {
      if (this._linesCache[side]) {
        return this._linesCache[side];
      }
      let lines = [];
      const key = side === 'left' ? 'a' : 'b';
      for (const chunk of this.diff.content) {
        if (chunk.ab) {
          lines = lines.concat(chunk.ab);
        } else if (chunk[key]) {
          lines = lines.concat(chunk[key]);
        }
      }
      this._linesCache[side] = lines;
      return lines;
    },

    /**
     * Query the diffElement for comments and check whether they lie inside the
     * selection range.
     *
     * @param {!Selection} sel The selection of the window.
     * @param {!string} side The side that is currently selected.
     * @return {string} The selected comment text.
     */
    _getCommentLines(sel, side) {
      const range = GrRangeNormalizer.normalize(sel.getRangeAt(0));
      const content = [];
      // Query the diffElement for comments.
      const messages = this.diffBuilder.diffElement.querySelectorAll(
          `.side-by-side [data-side="${side
          }"] .message *, .unified .message *`);

      for (let i = 0; i < messages.length; i++) {
        const el = messages[i];
        // Check if the comment element exists inside the selection.
        if (sel.containsNode(el, true)) {
          // Padded elements require newlines for accurate spacing.
          if (el.parentElement.id === 'container' ||
              el.parentElement.nodeName === 'BLOCKQUOTE') {
            if (content.length && content[content.length - 1] !== '') {
              content.push('');
            }
          }

          if (el.id === 'output' &&
              !this._elementDescendedFromClass(el, 'collapsed')) {
            content.push(this._getTextContentForRange(el, sel, range));
          }
        }
      }

      return content.join('\n');
    },

    /**
     * Given a DOM node, a selection, and a selection range, recursively get all
     * of the text content within that selection.
     * Using a domNode that isn't in the selection returns an empty string.
     *
     * @param {!Node} domNode The root DOM node.
     * @param {!Selection} sel The selection.
     * @param {!Range} range The normalized selection range.
     * @return {string} The text within the selection.
     */
    _getTextContentForRange(domNode, sel, range) {
      if (!sel.containsNode(domNode, true)) { return ''; }

      let text = '';
      if (domNode instanceof Text) {
        text = domNode.textContent;
        if (domNode === range.endContainer) {
          text = text.substring(0, range.endOffset);
        }
        if (domNode === range.startContainer) {
          text = text.substring(range.startOffset);
        }
      } else {
        for (const childNode of domNode.childNodes) {
          text += this._getTextContentForRange(childNode, sel, range);
        }
      }
      return text;
    },
  });
})();
