// 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/strings/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 base::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());
  // If aria-labelledby is empty or undefined, the aria-label attribute ... is
  // used (defined below).
  std::vector<std::string> ids =
      base::SplitString(attributes.value_or(""), base::kWhitespaceASCII,
                        base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  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, base::TRIM_ALL, &trimmed);
  if (!trimmed.empty()) {
    alternatives_.push_back(trimmed);
  }
  return !trimmed.empty();
}

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