// Copyright 2017 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/accessibility/internal/text_alternative_helper.h"

#include <utility>

#include "base/string_split.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/html_element.h"
#include "cobalt/dom/html_image_element.h"
#include "cobalt/dom/node_list.h"

namespace cobalt {
namespace accessibility {
namespace internal {
namespace {
// Helper class that inserts a base::Token into a base::hash_set during the
// class's lifetime.
class ScopedIdSetMember {
 public:
  // Adds |token| into |hash_set| for the duration of this class instance's
  // lifetime. If |token| is an empty string, it doesn't get added to the set.
  //
  // TextAlternativeHelper::visited_element_ids_ is used to keep track of a set
  // of element ids that have been visited during the current computation to
  // ensure that we do not follow any ID reference loops. When
  // AppendTextAlternative is called, the ID of that element is pushed into the
  // set using this helper class, so that the ID will be popped back out of the
  // set which allows us to re-visit that element in a non-recursive manner, if
  // necessary.
  ScopedIdSetMember(base::hash_set<base::Token>* hash_set,
                    const base::Token& token)
      : hash_set_(hash_set) {
    // Ignore empty tokens.
    if (SbStringGetLength(token.c_str()) > 0) {
      DCHECK(hash_set_->find(token) == hash_set_->end());
      iterator_pair_ = hash_set_->insert(token);
      DCHECK(iterator_pair_.second);
    } else {
      // Ensure iterator_pair_ is initialized.
      iterator_pair_ = std::make_pair(hash_set_->end(), false);
    }
  }
  ~ScopedIdSetMember() {
    if (iterator_pair_.second) {
      hash_set_->erase(iterator_pair_.first);
    }
  }

 private:
  base::hash_set<base::Token>* hash_set_;
  std::pair<base::hash_set<base::Token>::iterator, bool> iterator_pair_;
};

// Look up an element whose id is |id| in the document that |element| is in.
scoped_refptr<dom::Element> GetElementById(
    const scoped_refptr<dom::Element>& element, const std::string& id) {
  // TODO: If referenced elements tend to be close to the referencing element,
  // it may be more efficient to do a breadth-first search starting from
  // |element|.
  dom::Document* document = element->node_document();
  scoped_refptr<dom::Element> target_element = document->GetElementById(id);
  DLOG_IF(WARNING, !target_element) << "Could not find aria-labelledby target: "
                                    << id;
  return target_element;
}
}  // namespace

void TextAlternativeHelper::AppendTextAlternative(
    const scoped_refptr<dom::Node>& node) {
  DCHECK(node);
  // https://www.w3.org/TR/2014/REC-wai-aria-implementation-20140320/#mapping_additional_nd_te
  // 5.6.1.3. Text Alternative Computation

  if (node->IsText()) {
    // Rule 3D
    // Get the contents of the text node.
    if (node->text_content()) {
      AppendTextIfNonEmpty(*node->text_content());
    }
    return;
  }

  scoped_refptr<dom::Element> element = node->AsElement();
  if (!element) {
    // Since this is neither a Text or Element, ignore it.
    return;
  }

  if (visited_element_ids_.find(element->id()) != visited_element_ids_.end()) {
    DLOG(INFO) << "Skipping element to prevent reference loop: "
               << element->id();
    return;
  }

  ScopedIdSetMember scoped_id_set_member(&visited_element_ids_, element->id());

  // Rule 1
  // Skip hidden elements unless the author specifies to use them via an
  // aria-labelledby or aria-describedby being used in the current computation.
  if (!in_labelled_by_or_described_by_ && IsAriaHidden(element)) {
    return;
  }

  // Rule 2A (first bullet point)
  // The aria-labelledby attribute takes precedence as the element's text
  // alternative unless this computation is already occurring as the result of a
  // recursive aria-labelledby declaration.
  if (!in_labelled_by_or_described_by_) {
    if (TryAppendFromLabelledByOrDescribedBy(element,
                                             base::Tokens::aria_labelledby())) {
      return;
    }
  }

  // Rule 2A (second bullet point)
  // If aria-labelledby is empty or undefined, the aria-label attribute, which
  // defines an explicit text string, is used. However, if this computation is
  // already occurring as the result of a recursive text alternative computation
  // and the current element is an embedded control as defined in rule 2B,
  // ignore the aria-label attribute and skip directly to rule 2B.
  //
  // Note: Cobalt doesn't support the embedded controls defined in rule 2B, so
  // just get the alternative text from the label, if it exists.
  if (TryAppendFromLabel(element)) {
    return;
  }

  // Rule 2A (third bullet point)
  // If aria-labelledby and aria-label are both empty or undefined, and if the
  // element is not marked as presentational (role="presentation", check for the
  // presence of an equivalent host language attribute or element for
  // associating a label, and use those mechanisms to determine a text
  // alternative. For example, in HTML, the img element's alt attribute defines
  // a label string and the label element references the form element it labels.
  //
  // This implementation does not support the "role" attribute, so just get the
  // "alt" property, if this is an element that supports it
  if (TryAppendFromAltProperty(element)) {
    return;
  }

  // Rule 2B
  // Cobalt does not support the controls described in this step, so skip it.

  // Rule 2C
  // Otherwise, if the attributes checked in rules A and B didn't provide
  // results, text is collected from descendant content if the current element's
  // role allows "Name From: contents." The text alternatives for child nodes
  // will be concatenated, using this same set of rules. This same rule may
  // apply to a child, which means the computation becomes recursive and can
  // result in text being collected in all the nodes in this subtree, no matter
  // how deep they are. However, any given descendant subtree may instead
  // collect their part of the text alternative from the preferred markup
  // described in A and B above. These author-specified attributes are assumed
  // to provide the correct text alternative for the entire subtree. All in all,
  // the node rules are applied consistently as text alternatives are collected
  // from descendants, and each containing element in those descendants may or
  // may not allow their contents to be used. Each node in the subtree is
  // consulted only once. If text has been collected from a child node, and is
  // referenced by another IDREF in some descendant node, then that second, or
  // subsequent, reference is not followed. This is done to avoid infinite
  // loops.
  //
  // The "role" attribute is not supported, so ignore it. Recurse through
  // children and concatenate text alternatives.
  scoped_refptr<dom::NodeList> children = element->child_nodes();
  for (int i = 0; i < children->length(); ++i) {
    scoped_refptr<dom::Node> child = children->Item(i);
    AppendTextAlternative(child);
  }

  // 5.6.1.2. Description Compution
  // If aria-describedby is present, user agents MUST compute the accessible
  // description by concatenating the text alternatives for nodes referenced by
  // an aria-describedby attribute on the current node. The text alternatives
  // for the referenced nodes are computed using a number of methods.
  if (!in_labelled_by_or_described_by_) {
    TryAppendFromLabelledByOrDescribedBy(element,
                                         base::Tokens::aria_describedby());
  }
}

std::string TextAlternativeHelper::GetTextAlternative() {
  return JoinString(alternatives_, ' ');
}

bool TextAlternativeHelper::IsAriaHidden(
    const scoped_refptr<dom::Element>& element) {
  if (!element) {
    return false;
  }
  base::optional<std::string> aria_hidden_attribute =
      element->GetAttribute(base::Tokens::aria_hidden().c_str());
  if (aria_hidden_attribute.value_or("") == base::Tokens::true_token()) {
    return true;
  }
  return IsAriaHidden(element->parent_element());
}

bool TextAlternativeHelper::TryAppendFromLabelledByOrDescribedBy(
    const scoped_refptr<dom::Element>& element, const base::Token& token) {
  DCHECK(!in_labelled_by_or_described_by_);
  base::optional<std::string> attributes = element->GetAttribute(token.c_str());
  std::vector<std::string> ids;
  // If aria-labelledby is empty or undefined, the aria-label attribute ... is
  // used (defined below).
  base::SplitStringAlongWhitespace(attributes.value_or(""), &ids);
  const size_t current_num_alternatives = alternatives_.size();
  if (!ids.empty()) {
    in_labelled_by_or_described_by_ = true;
    for (int i = 0; i < ids.size(); ++i) {
      if (visited_element_ids_.find(base::Token(ids[i])) !=
          visited_element_ids_.end()) {
        DLOG(WARNING) << "Skipping reference to ID: " << ids[i]
                      << " to prevent reference loop.";
        continue;
      }
      scoped_refptr<dom::Element> target_element =
          GetElementById(element, ids[i]);
      if (!target_element) {
        DLOG(WARNING) << "Could not find " << token.c_str()
                      << " target: " << ids[i];
        continue;
      }
      AppendTextAlternative(target_element);
    }
    in_labelled_by_or_described_by_ = false;
  }
  // Check if any of these recursive calls to AppendTextAlternative actually
  // ended up appending something.
  return current_num_alternatives != alternatives_.size();
}

bool TextAlternativeHelper::TryAppendFromLabel(
    const scoped_refptr<dom::Element>& element) {
  base::optional<std::string> label_attribute =
      element->GetAttribute(base::Tokens::aria_label().c_str());
  return AppendTextIfNonEmpty(label_attribute.value_or(""));
}

bool TextAlternativeHelper::TryAppendFromAltProperty(
    const scoped_refptr<dom::Element>& element) {
  // https://www.w3.org/TR/REC-html40/struct/objects.html#h-13.8
  // The only element type that supports the "alt" attribute that Cobalt
  // implements is the <img> element.
  if (element->AsHTMLElement() &&
      element->AsHTMLElement()->AsHTMLImageElement()) {
    base::optional<std::string> alt_attribute =
        element->GetAttribute(base::Tokens::alt().c_str());
    if (alt_attribute) {
      return AppendTextIfNonEmpty(*alt_attribute);
    }
  }
  return false;
}

bool TextAlternativeHelper::AppendTextIfNonEmpty(const std::string& text) {
  std::string trimmed;
  TrimWhitespaceASCII(text, TRIM_ALL, &trimmed);
  if (!trimmed.empty()) {
    alternatives_.push_back(trimmed);
  }
  return !trimmed.empty();
}

}  // namespace internal
}  // namespace accessibility
}  // namespace cobalt
