/*
 * 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::Element>& element) {
  DCHECK(element);
  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());

  // https://www.w3.org/TR/2014/REC-wai-aria-implementation-20140320/#mapping_additional_nd_te
  // 5.6.1.3. Text Alternative Computation

  // 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);
    if (child->IsElement()) {
      AppendTextAlternative(child->AsElement());
    } else if (child->IsText()) {
      // Rule 3D
      // Get the contents of the text node.
      if (child->text_content()) {
        AppendTextIfNonEmpty(*child->text_content());
      }
    }
  }
}

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->tag_name() == dom::HTMLImageElement::kTagName) {
    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
