// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// 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.

#include "cobalt/webdriver/algorithms.h"

#include <algorithm>
#include <cstring>
#include <functional>
#include <vector>

#include "base/string_util.h"
#include "cobalt/cssom/css_computed_style_data.h"
#include "cobalt/cssom/string_value.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/html_body_element.h"
#include "cobalt/dom/html_br_element.h"
#include "cobalt/dom/html_head_element.h"
#include "cobalt/dom/node.h"
#include "cobalt/dom/node_list.h"
#include "cobalt/math/rect.h"
#include "third_party/icu/source/common/unicode/unistr.h"

namespace cobalt {
namespace webdriver {
namespace algorithms {
namespace {
// Characters that match \s in ECMAScript regular expressions.
// Note that non-breaking space is at the beginning to simplify definition of
// kWhitespaceCharsExcludingNonBreakingSpace below.
const char32_t kWhitespaceChars[] =
    U"\u00a0 "
    U"\f\n\r\t\v\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006"
    U"\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\ufeff";
const char32_t* kWhitespaceCharsExcludingNonBreakingSpace =
    kWhitespaceChars + 1;

// Defined in https://www.w3.org/TR/webdriver/#text.horizontal
const char32_t kHorizontalWhitespaceChars[] = U" \f\t\v\u2028\u2029";

// Defined in step 2.1 of the getElementText() algorithm in
// https://www.w3.org/TR/webdriver/#get-element-text
const char32_t kZeroWidthSpacesAndFeeds[] = U"\f\v\u200b\u200e\u200f";

const char32_t kNonBreakingSpace[] = U"\u00a0";

const char32_t kIcuEndOfString = 0xffff;

bool StringContains(const char32_t* str, char32_t ch) {
  for (size_t i = 0; str[i] != 0; ++i) {
    if (ch == str[i]) {
      return true;
    }
  }
  return false;
}

void RemoveCharacters(icu::UnicodeString* text, const char32_t* characters) {
  for (int32_t text_offset = 0;;) {
    char32_t ch = text->char32At(text_offset);
    if (ch == kIcuEndOfString) {
      return;
    }
    if (StringContains(characters, ch)) {
      text->remove(text_offset, 1);
    } else {
      ++text_offset;
    }
  }
}

void ReplaceCharacters(icu::UnicodeString* text, const char32_t* characters,
                       char32_t new_character) {
  for (int32_t text_offset = 0;; ++text_offset) {
    char32_t ch = text->char32At(text_offset);
    if (ch == kIcuEndOfString) {
      return;
    }
    if (StringContains(characters, ch)) {
      text->replace(text_offset, 1, UChar32(new_character));
    }
  }
}

void TrimUnicodeString(icu::UnicodeString* text, const char32_t* characters) {
  // Trim characters at the end.
  int32_t original_length = text->length();
  for (int32_t text_offset = original_length - 1;; --text_offset) {
    if (text_offset < 0 && original_length > 0) {
      text->remove();
    }
    char32_t ch = text->char32At(text_offset);
    if (!StringContains(characters, ch)) {
      ++text_offset;
      if (text_offset < original_length) {
        text->remove(text_offset, original_length - text_offset);
      }
      break;
    }
  }

  // Trim characters at the beginning.
  for (int32_t text_offset = 0;; ++text_offset) {
    char32_t ch = text->char32At(text_offset);
    if (ch == kIcuEndOfString || !StringContains(characters, ch)) {
      if (text_offset > 0) {
        text->remove(0, text_offset);
      }
      break;
    }
  }
}

bool IsInHeadElement(dom::Element* element) {
  if (element->AsHTMLElement() &&
      element->AsHTMLElement()->AsHTMLHeadElement()) {
    return true;
  }
  scoped_refptr<dom::Element> parent = element->parent_element();
  if (parent == NULL) {
    return false;
  }
  return IsInHeadElement(parent.get());
}

void CanonicalizeText(const base::optional<std::string>& whitespace_style,
                      const base::optional<std::string>& text_transform,
                      icu::UnicodeString* text) {
  // https://www.w3.org/TR/webdriver/#get-element-text
  // 2.1 Remove any zero-width spaces (\u200b, \u200e, \u200f), form feeds (\f)
  // or vertical tab feeds (\v) from text.
  RemoveCharacters(text, kZeroWidthSpacesAndFeeds);

  // Consecutive sequences of new lines should be compressed to a single new
  // line. Accomplish this by converting all \r chars to \n chars, and then
  // converting sequences of \n chars to a single \n char.
  ReplaceCharacters(text, U"\r", '\n');

  const icu::UnicodeString consecutive_newline = UNICODE_STRING_SIMPLE("\n\n");
  for (int32_t index = text->indexOf(consecutive_newline); index >= 0;
       index = text->indexOf(consecutive_newline, index)) {
    text->remove(index, 1);
  }

  // https://www.w3.org/TR/webdriver/#get-element-text
  // 2.3
  if (whitespace_style) {
    // If the parent's effective CSS whitespace style is 'normal' or 'nowrap'
    // replace each newline (\n) in text with a single space character (\x20).
    if (*whitespace_style == cssom::kNormalKeywordName ||
        *whitespace_style == cssom::kNoWrapKeywordName) {
      ReplaceCharacters(text, U"\n", ' ');
    }

    // If the parent's effective CSS whitespace style is 'pre' or 'pre-wrap'
    // replace each horizontal whitespace character with a non-breaking space
    // character (\u00a0).
    // Otherwise replace each sequence of horizontal whitespace characters
    // except non-breaking spaces (\u00a0) with a single space character.
    //
    // Cobalt does not have 'pre-wrap' style, so just check for 'pre'.
    if (*whitespace_style == cssom::kPreKeywordName) {
      ReplaceCharacters(text, kHorizontalWhitespaceChars, kNonBreakingSpace[0]);
    } else {
      // Replace all horizontal whitespace characters with ' '.
      ReplaceCharacters(text, kHorizontalWhitespaceChars, ' ');
      // Convert consecutive ' ' characters to a single ' '.
      const icu::UnicodeString consecutive_space = UNICODE_STRING_SIMPLE("  ");
      for (int32_t index = text->indexOf(consecutive_space); index >= 0;
           index = text->indexOf(consecutive_space, index)) {
        text->remove(index, 1);
      }
    }
  }

  // https://www.w3.org/TR/webdriver/#get-element-text
  // 2.4 Apply the parent's effective CSS text-transform style as per the
  // CSS 2.1 specification ([CSS21])
  if (text_transform) {
    // Cobalt does not support 'capitalize' and 'lowercase' keywords.
    if (*text_transform == cssom::kUppercaseKeywordName) {
      text->toUpper();
    }
  }
}

// Helper template function to get the computed style from a
// cssom::CSSComputedStyleData member function getter.
template <typename style_getter_function>
base::optional<std::string> GetComputedStyle(dom::Element* element,
                                             style_getter_function getter) {
  scoped_refptr<dom::HTMLElement> html_element(element->AsHTMLElement());
  DCHECK(html_element);
  if (html_element->computed_style()) {
    scoped_refptr<cssom::PropertyValue> property_value =
        (html_element->computed_style()->*getter)();
    if (property_value) {
      return property_value->ToString();
    }
  }
  return base::nullopt;
}

// https://www.w3.org/TR/webdriver/#text.blocklevel
bool IsBlockLevelElement(dom::Element* element) {
  base::optional<std::string> display_style =
      GetComputedStyle(element, &cssom::CSSComputedStyleData::display);
  if (display_style) {
    if (*display_style == cssom::kInlineKeywordName ||
        *display_style == cssom::kInlineBlockKeywordName ||
        *display_style == cssom::kNoneKeywordName) {
      // inline-table, table-cell, table-column, table-column-group are not
      // supported by Cobalt.
      return false;
    }
  }
  return true;
}

// Return true if there is at least one string in the vector and the last one
// is non-empty.
bool LastLineIsNonEmpty(const std::vector<icu::UnicodeString>& lines) {
  if (lines.empty()) {
    return false;
  }
  return !lines.back().isEmpty();
}

// Recursive function to build the vector of lines for the text representation
// of an element.
void GetElementTextInternal(dom::Element* element,
                            std::vector<icu::UnicodeString>* lines) {
  // If the element is a: BR element: Push '' to lines and continue.
  if (element->AsHTMLElement() && element->AsHTMLElement()->AsHTMLBRElement()) {
    lines->push_back("");
    return;
  }

  bool is_block = IsBlockLevelElement(element);

  // If the element is a: Block-level element and if last(lines) is not '',
  // push '' to lines.
  if (is_block && LastLineIsNonEmpty(*lines)) {
    lines->push_back("");
  }

  // These styles are needed for the text nodes.
  base::optional<std::string> whitespace_style =
      GetComputedStyle(element, &cssom::CSSComputedStyleData::white_space);
  base::optional<std::string> text_transform_style =
      GetComputedStyle(element, &cssom::CSSComputedStyleData::text_transform);

  bool is_displayed = IsDisplayed(element);

  scoped_refptr<dom::NodeList> children = element->child_nodes();
  // https://www.w3.org/TR/webdriver/#get-element-text
  // 2. For each descendent of node, at time of execution, in order:
  for (uint32 i = 0; i < children->length(); ++i) {
    scoped_refptr<dom::Node> child = children->Item(i);
    if (child->IsText() && is_displayed) {
      // If descendent is a [DOM] text node let text equal the nodeValue
      // property of descendent.
      icu::UnicodeString text = icu::UnicodeString::fromUTF8(
          child->node_value().value_or(""));
      CanonicalizeText(whitespace_style, text_transform_style, &text);

      // 2.5 If last(lines) ends with a space character and text starts with a
      // space character, trim the first character of text.
      // 2.6 Append text to last(lines) in-place.
      if (lines->empty()) {
        lines->push_back(text);
      } else {
        if (lines->back().endsWith(' ') && text.startsWith(' ')) {
          text.remove(0, 1);
        }
        lines->back().append(text);
      }
    } else if (child->IsElement()) {
      scoped_refptr<dom::Element> child_element = child->AsElement();
      GetElementTextInternal(child_element.get(), lines);
    }
  }

  if (is_block && LastLineIsNonEmpty(*lines)) {
    lines->push_back("");
  }
}

bool DisplayStyleIsNone(dom::Element* element) {
  base::optional<std::string> display_style =
      GetComputedStyle(element, &cssom::CSSComputedStyleData::display);
  return display_style && *display_style == cssom::kNoneKeywordName;
}

// Return true if opacity is set to zero.
bool IsTransparent(dom::Element* element) {
  base::optional<std::string> opacity_style =
      GetComputedStyle(element, &cssom::CSSComputedStyleData::opacity);
  return opacity_style && *opacity_style == "0";
}

// Return true if this element and all its ancestors have display style set to
// none.
bool AreElementAndAncestorsDisplayed(dom::Element* element) {
  DCHECK(element);
  if (DisplayStyleIsNone(element)) {
    return false;
  }
  scoped_refptr<dom::Element> parent = element->parent_element();
  return !parent || AreElementAndAncestorsDisplayed(parent.get());
}

// Returns true if this element has non-zero dimensions, or if any of its
// children have non-zero dimensions and this element's overflow style is not
// set to hidden.
bool HasPositiveSizeDimensions(dom::Element* element) {
  DCHECK(element);
  scoped_refptr<dom::DOMRect> rect = element->GetBoundingClientRect();
  DCHECK(rect);
  if (rect->height() > 0 && rect->width() > 0) {
    return true;
  }
  // Zero-sized elements should still be considered to have positive size
  // if they have a child element or text node with positive size, unless
  // the element has an 'overflow' style of 'hidden'.
  base::optional<std::string> overflow_style =
      GetComputedStyle(element, &cssom::CSSComputedStyleData::overflow);
  if (overflow_style && *overflow_style == cssom::kHiddenKeywordName) {
    return false;
  }
  scoped_refptr<dom::NodeList> child_nodes = element->child_nodes();
  DCHECK(child_nodes);
  for (uint32 i = 0; i < child_nodes->length(); ++i) {
    scoped_refptr<dom::Node> child = child_nodes->Item(i);
    if (child->IsText() ||
        (child->IsElement() && HasPositiveSizeDimensions(child->AsElement()))) {
      return true;
    }
  }
  // Neither this element nor any of its children have positive size dimensions.
  return false;
}

math::Rect GetRect(dom::Element* element) {
  scoped_refptr<dom::DOMRect> element_rect = element->GetBoundingClientRect();
  math::RectF rect(element_rect->x(), element_rect->y(), element_rect->width(),
                   element_rect->height());
  return math::Rect::RoundFromRectF(rect);
}

// Returns true if this element is completely hidden by overflow.
bool IsHiddenByOverflow(dom::Element* element) {
  math::Rect element_rect = GetRect(element);
  // Check each ancestor of this element and if the ancestor's overflow style
  // is set to hidden, check if this element completely overflows or underflows
  // the element and is thus not visible.
  dom::Element* parent = element->parent_element();
  while (parent) {
    // Only block level elements will hide children due to overflow.
    if (IsBlockLevelElement(parent)) {
      // Cobalt doesn't support overflow-x or overflow-y, so just check for
      // overflow.
      base::optional<std::string> overflow_style =
          GetComputedStyle(parent, &cssom::CSSComputedStyleData::overflow);
      if (overflow_style && *overflow_style == cssom::kHiddenKeywordName) {
        // Get the parent's rect. If the element's rect does not intersect the
        // parent's rect, then it is hidden by overflow.
        math::Rect parent_rect = GetRect(parent);
        if (!element_rect.Intersects(parent_rect)) {
          return true;
        }
      }
    }
    parent = parent->parent_element();
  }
  return false;
}

// Returns true if this element and all its children are completely hidden
// due to overflow.
bool AreElementAndChildElementsHiddenByOverflow(dom::Element* element) {
  if (!IsHiddenByOverflow(element)) {
    return false;
  }
  scoped_refptr<dom::NodeList> child_nodes = element->child_nodes();
  DCHECK(child_nodes);
  // Check if all child elements are also hidden by overflow.
  for (uint32 i = 0; i < child_nodes->length(); ++i) {
    scoped_refptr<dom::Node> child = child_nodes->Item(i);
    if (child->IsElement()) {
      scoped_refptr<dom::Element> child_as_element = child->AsElement();
      if (AreElementAndChildElementsHiddenByOverflow(child_as_element.get()) ||
          !HasPositiveSizeDimensions(child_as_element.get())) {
        return false;
      }
    }
  }
  // All child elements are hidden by overflow.
  return true;
}

}  // namespace

std::string GetElementText(dom::Element* element) {
  DCHECK(element);

  // https://www.w3.org/TR/webdriver/#get-element-text
  // 1. If the element is in the head element of the document, return an empty
  // string.
  if (IsInHeadElement(element)) {
    return "";
  }

  // Update the computed styles first to ensure we get up-to-date computed
  // styles.
  DCHECK(element->node_document());
  element->node_document()->UpdateComputedStyles();

  // Recursively visit this element and its children to create a vector of lines
  // of text.
  std::vector<icu::UnicodeString> lines;
  GetElementTextInternal(element, &lines);

  // Trim leading and trailing non-breaking space characters in each line in
  // place. Also replace non-breaking spaces with regular spaces.
  for (size_t i = 0; i < lines.size(); ++i) {
    TrimUnicodeString(&lines[i], kWhitespaceCharsExcludingNonBreakingSpace);
    ReplaceCharacters(&lines[i], kNonBreakingSpace, ' ');
  }

  // Join the lines, and trim any leading/trailing newlines.
  std::string joined;
  if (!lines.empty()) {
    lines[0].toUTF8String(joined);
    for (size_t i = 1; i < lines.size(); ++i) {
      joined.append("\n");
      lines[i].toUTF8String(joined);
    }
    TrimString(joined, "\n", &joined);
  }

  return joined;
}

// There is a spec for "displayedness" available:
//   https://w3c.github.io/webdriver/webdriver-spec.html#element-displayedness
// However, the algorithm described in the spec does not match existing
// implementations of WebDriver.
// IsDisplayed will match the existing implementations, using the implementation
// in selenium's github repository as a reference.
// https://github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/dom.js#L577
bool IsDisplayed(dom::Element* element) {
  DCHECK(element);

  // By convention, BODY element is always shown: BODY represents the document
  // and even if there's nothing rendered in there, user can always see there's
  // the document.
  if (element->AsHTMLElement() &&
      element->AsHTMLElement()->AsHTMLBodyElement()) {
    return true;
  }

  // Update the computed styles first to ensure we get up-to-date computed
  // styles.
  if (element->AsHTMLElement()) {
    DCHECK(element->node_document());
    // If the element is an HTML element, we can update for only its subtree.
    element->node_document()->UpdateComputedStyleOnElementAndAncestor(
        element->AsHTMLElement());
  } else {
    DCHECK(element->node_document());
    element->node_document()->UpdateComputedStyles();
  }

  // Any element with hidden/collapsed visibility is not shown.
  base::optional<std::string> visiblity_style =
      GetComputedStyle(element, &cssom::CSSComputedStyleData::visibility);
  if (visiblity_style && *visiblity_style == cssom::kHiddenKeywordName) {
    return false;
  }

  // If element and its ancestors are not displayed, return false.
  if (!AreElementAndAncestorsDisplayed(element)) {
    return false;
  }

  if (IsTransparent(element)) {
    return false;
  }

  // Any element without positive size dimensions is not shown.
  if (!HasPositiveSizeDimensions(element)) {
    return false;
  }

  if (IsHiddenByOverflow(element)) {
    scoped_refptr<dom::NodeList> child_nodes = element->child_nodes();
    DCHECK(child_nodes);
    // If all children are hidden, then this one is hidden.
    for (uint32 i = 0; i < child_nodes->length(); ++i) {
      scoped_refptr<dom::Node> child = child_nodes->Item(i);
      scoped_refptr<dom::Element> child_as_element = child->AsElement();
      bool child_is_hidden = !child_as_element ||
                             IsHiddenByOverflow(child_as_element.get()) ||
                             !HasPositiveSizeDimensions(child_as_element.get());
      if (!child_is_hidden) {
        return true;
      }
    }
    return false;
  }
  return true;
}

}  // namespace algorithms
}  // namespace webdriver
}  // namespace cobalt
