/*
 * Copyright 2014 Google Inc.
 *
 * 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.
 */

/**
 * @fileoverview JS class for finding below-the-fold XPaths used by split_html.
 */

goog.provide('pagespeedutils.CriticalXPaths');
goog.provide('pagespeedutils.generateXPath');

goog.require('pagespeedutils');



/**
 * @constructor
 * @param {number} viewportWidth Width of the viewport.
 * @param {number} viewportHeight Height of the viewport.
 * @param {Node} document The root document.
 */
pagespeedutils.CriticalXPaths = function(
    viewportWidth, viewportHeight, document) {
  /**
   * Viewport size.
   * @type {{ height: (number), width: (number) }}
   * @private
   */
  this.windowSize_ = {
    'height': viewportHeight,
    'width': viewportWidth
  };

  /**
   * List of xpath pairs in the form start_xpath:end_xpath.
   * @type {Array.<string>}
   * @private
   */
  this.xpathPairs_ = [];

  this.document_ = document;
};


/**
 * Gets the start and end xpath for the non-critical panels.
 * @return {Array.<string>}
 */
pagespeedutils.CriticalXPaths.prototype.getNonCriticalPanelXPathPairs =
    function() {
  // We only need to mark elements in the body. Elements in the head are never
  // visible.
  this.findNonCriticalPanelBoundaries_(this.document_.body);

  return this.xpathPairs_;
};


/**
 * Appends Appends a new XPath to the current list of XPath pairs.
 * @param {string} startXpath Start XPath.
 * @param {string} endXpath End XPath.
 * @private
 */
pagespeedutils.CriticalXPaths.prototype.addXPathPair_ = function(startXpath,
    endXpath) {
  if (!startXpath) {
    return;
  }
  var xpathPair = startXpath;
  if (endXpath) {
    xpathPair += ':' + endXpath;
  }
  this.xpathPairs_.push(xpathPair);
};


/**
 * Identifies all nodes which are not in viewport and populates the start and
 * end xpath of non-critical panels into xpathPairs_.
 * @param  {!Node} node Dom node.
 * @return {boolean} true iff node in viewport or any of node's
 * descendants is critical.
 * @private
 */
pagespeedutils.CriticalXPaths.prototype.findNonCriticalPanelBoundaries_ =
    function(node) {
  var nodeIsCritical = pagespeedutils.inViewport(node, this.windowSize_);
  var prevChildIsCritical = nodeIsCritical;
  // The loop below determines the XPaths at the transition points of nodes
  // going from critical to non-critical. startChildXPath will be the first
  // non-critical node, and endChildXPath will be the first critical node after
  // the non-critical section.
  var startChildXPath = '';
  var endChildXPath = '';
  // Iterate over the visible (that is, not hidden, independent of viewport
  // size) sibling nodes of the passed in node.
  var firstChild = this.visibleNodeOrSibling_(node.firstChild);
  for (var currNode = firstChild; currNode != null;
       currNode = this.visibleNodeOrSibling_(currNode.nextSibling)) {
    // Check if we are at a criticality transition point by making a recursive
    // call to findNonCriticalPanelBoundaries for the current sibling node. If
    // we are at a transition point from critical to non-critical, we need to
    // mark the current sibling node as the start of an XPath. If we are
    // transitioning from non-critical to critical, then the current node is the
    // end of our XPath, and we need to store the complete path.
    // TODO(jud): The logic here is tricky to follow. See if we can simplify
    // this to make it clearer and more efficient.
    var currNodeIsCritical = this.findNonCriticalPanelBoundaries_(currNode);
    if (currNodeIsCritical != prevChildIsCritical) {
      if (!currNodeIsCritical) {
        // Going from critical -> non-critical.
        startChildXPath = pagespeedutils.generateXPath(
            currNode, this.document_);
        endChildXPath = '';
      } else {
        // Going from non-critical -> critical
        if (!nodeIsCritical) {
          // But non-critical panel never began.
          // All the nodes till currNode are non-critical.
          if (firstChild != currNode) {
            startChildXPath = pagespeedutils.generateXPath(
                firstChild, this.document_);
          }
          nodeIsCritical = true;
        }
        endChildXPath = pagespeedutils.generateXPath(currNode, this.document_);
        if (!endChildXPath) {
          // If 'endChildXPath' is empty here, then it is better not to split
          // here than treating few critical nodes as non-critical.
          startChildXPath = '';
        }
        if (startChildXPath) {
          this.addXPathPair_(startChildXPath, endChildXPath);
        }
        startChildXPath = '';
      }
      prevChildIsCritical = currNodeIsCritical;
    }
  }
  if (startChildXPath) {
    this.addXPathPair_(startChildXPath, endChildXPath);
  }
  return nodeIsCritical;
};


/**
 * Generates the xpath for the given node which is relative to body.
 * @param {Node} node Node in dom tree whose xpath is generated.
 * @param {Node} doc Page document.
 * @return {string} xpath of a node which is always a rendered one.
 */
pagespeedutils.generateXPath = function(node, doc) {
  var xpathUnits = [];
  while (node != doc.body) {
    var id = node.getAttribute('id');
    if (id && doc.querySelectorAll('#' + id).length == 1) {
      // Use 'id' inside xpath only if it is used once in the document.
      xpathUnits.unshift(node.tagName.toLowerCase() + '[@id=\"' +
          node.getAttribute('id') + '\"]');
      break;
    } else {
      var i = 0;
      for (var sibling = node;
           sibling;
           sibling = sibling.previousElementSibling) {
        // Please keep this list of tags same as that in
        // google_critical_line_info_finder.cc.
        if ((sibling.tagName === 'SCRIPT') ||
            (sibling.tagName === 'NOSCRIPT') ||
            (sibling.tagName === 'STYLE') ||
            (sibling.tagName === 'LINK')) {
          continue;
        }
        ++i;
      }
      xpathUnits.unshift(node.tagName.toLowerCase() + '[' + i + ']');
    }
    node = node.parentNode;
  }
  return xpathUnits.length ? xpathUnits.join('/') : '';
};


/**
 * @param {Node} node Node in DOM tree.
 * @return {?Node} Returns node if it is visible (as in width and height greater
 *     than 0, irrespective of the viewport), or the first visible sibling of
 *     node if it isn't. Returns null if no valid nodes are found.
 * @private
 */
pagespeedutils.CriticalXPaths.prototype.visibleNodeOrSibling_ = function(node) {
  for (; node != null; node = node.nextSibling) {
    if (node.nodeType != Node.ELEMENT_NODE) continue;
    if (node.offsetWidth == 0 && node.offsetHeight == 0) continue;
    // Also check node.offsetParent to see if the node is hidden. offsetParent
    // is null when the node has display:none or position:fixed styling, or if
    // it's a body node. To differentiate, we explicitly check for
    // position:fixed and body and do not consider those cases hidden.
    if (node.offsetParent || node.tagName == 'BODY' ||
        node.style.position == 'fixed') return node;
  }
  return null;
};
