// Copyright 2017 Google Inc. 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_ && 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_) {
    if (TryAppendFromLabelledBy(element)) {
      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);
  }
}

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::TryAppendFromLabelledBy(
    const scoped_refptr<dom::Element>& element) {
  DCHECK(!in_labelled_by_);
  base::optional<std::string> labelled_by_attribute =
      element->GetAttribute(base::Tokens::aria_labelledby().c_str());
  std::vector<std::string> labelled_by_ids;
  // If aria-labelledby is empty or undefined, the aria-label attribute ... is
  // used (defined below).
  base::SplitStringAlongWhitespace(labelled_by_attribute.value_or(""),
                                   &labelled_by_ids);
  const size_t current_num_alternatives = alternatives_.size();
  if (!labelled_by_ids.empty()) {
    in_labelled_by_ = true;
    for (int i = 0; i < labelled_by_ids.size(); ++i) {
      if (visited_element_ids_.find(base::Token(labelled_by_ids[i])) !=
          visited_element_ids_.end()) {
        DLOG(WARNING) << "Skipping reference to ID: " << labelled_by_ids[i]
                      << " to prevent reference loop.";
        continue;
      }
      scoped_refptr<dom::Element> labelled_by_element =
          GetElementById(element, labelled_by_ids[i]);
      if (!labelled_by_element) {
        DLOG(WARNING) << "Could not find aria-labelledby target: "
                      << labelled_by_ids[i];
        continue;
      }
      AppendTextAlternative(labelled_by_element);
    }
    in_labelled_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
