// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/aom/computed_accessible_node.h"

#include <stdint.h>
#include <memory>
#include <utility>

#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/renderer/core/accessibility/ax_context.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"

namespace blink {

class ComputedAccessibleNodePromiseResolver::RequestAnimationFrameCallback final
    : public FrameCallback {
 public:
  explicit RequestAnimationFrameCallback(
      ComputedAccessibleNodePromiseResolver* resolver)
      : resolver_(resolver) {}

  void Invoke(double) override {
    resolver_->continue_callback_request_id_ = 0;
    resolver_->UpdateTreeAndResolve();
  }

  void Trace(Visitor* visitor) const override {
    visitor->Trace(resolver_);
    FrameCallback::Trace(visitor);
  }

 private:
  Member<ComputedAccessibleNodePromiseResolver> resolver_;

  DISALLOW_COPY_AND_ASSIGN(RequestAnimationFrameCallback);
};

ComputedAccessibleNodePromiseResolver::ComputedAccessibleNodePromiseResolver(
    ScriptState* script_state,
    Element& element)
    : element_(element),
      resolver_(MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
      resolve_with_node_(false),
      ax_context_(std::make_unique<AXContext>(element_->GetDocument())) {}

ScriptPromise ComputedAccessibleNodePromiseResolver::Promise() {
  return resolver_->Promise();
}

void ComputedAccessibleNodePromiseResolver::Trace(Visitor* visitor) const {
  visitor->Trace(element_);
  visitor->Trace(resolver_);
}

void ComputedAccessibleNodePromiseResolver::ComputeAccessibleNode() {
  resolve_with_node_ = true;
  EnsureUpToDate();
}

void ComputedAccessibleNodePromiseResolver::EnsureUpToDate() {
  DCHECK(RuntimeEnabledFeatures::AccessibilityObjectModelEnabled());
  if (continue_callback_request_id_)
    return;
  // TODO(aboxhall): Trigger a call when lifecycle is next at kPrePaintClean.
  RequestAnimationFrameCallback* callback =
      MakeGarbageCollected<RequestAnimationFrameCallback>(this);
  continue_callback_request_id_ =
      element_->GetDocument().RequestAnimationFrame(callback);
}

void ComputedAccessibleNodePromiseResolver::UpdateTreeAndResolve() {
  LocalFrame* local_frame = element_->ownerDocument()->GetFrame();
  if (!local_frame) {
    resolver_->Resolve();
    return;
  }
  WebLocalFrameClient* client =
      WebLocalFrameImpl::FromFrame(local_frame)->Client();
  WebComputedAXTree* tree = client->GetOrCreateWebComputedAXTree();
  tree->ComputeAccessibilityTree();

  if (!resolve_with_node_) {
    resolver_->Resolve();
    return;
  }

  Document& document = element_->GetDocument();
  document.View()->UpdateLifecycleToCompositingCleanPlusScrolling(
      DocumentUpdateReason::kAccessibility);
  AXObjectCache& cache = ax_context_->GetAXObjectCache();
  AXID ax_id = cache.GetAXID(element_);

  ComputedAccessibleNode* accessible_node =
      document.GetOrCreateComputedAccessibleNode(ax_id, tree);
  resolver_->Resolve(accessible_node);
}

// ComputedAccessibleNode ------------------------------------------------------

ComputedAccessibleNode::ComputedAccessibleNode(AXID ax_id,
                                               WebComputedAXTree* tree,
                                               Document* document)
    : ax_id_(ax_id),
      tree_(tree),
      document_(document),
      ax_context_(std::make_unique<AXContext>(*document)) {}

base::Optional<bool> ComputedAccessibleNode::atomic() const {
  return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_ATOMIC);
}

base::Optional<bool> ComputedAccessibleNode::busy() const {
  return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_BUSY);
}

base::Optional<bool> ComputedAccessibleNode::disabled() const {
  return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_DISABLED);
}

base::Optional<bool> ComputedAccessibleNode::readOnly() const {
  return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_READONLY);
}

base::Optional<bool> ComputedAccessibleNode::expanded() const {
  return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_EXPANDED);
}

base::Optional<bool> ComputedAccessibleNode::modal() const {
  return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_MODAL);
}

base::Optional<bool> ComputedAccessibleNode::multiline() const {
  return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_MULTILINE);
}

base::Optional<bool> ComputedAccessibleNode::multiselectable() const {
  return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_MULTISELECTABLE);
}

base::Optional<bool> ComputedAccessibleNode::required() const {
  return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_REQUIRED);
}

base::Optional<bool> ComputedAccessibleNode::selected() const {
  return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_SELECTED);
}

base::Optional<int32_t> ComputedAccessibleNode::colCount() const {
  return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_COLUMN_COUNT);
}

base::Optional<int32_t> ComputedAccessibleNode::colIndex() const {
  return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_COLUMN_INDEX);
}

base::Optional<int32_t> ComputedAccessibleNode::colSpan() const {
  return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_COLUMN_SPAN);
}

base::Optional<int32_t> ComputedAccessibleNode::level() const {
  return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_HIERARCHICAL_LEVEL);
}

base::Optional<int32_t> ComputedAccessibleNode::posInSet() const {
  return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_POS_IN_SET);
}

base::Optional<int32_t> ComputedAccessibleNode::rowCount() const {
  return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_ROW_COUNT);
}

base::Optional<int32_t> ComputedAccessibleNode::rowIndex() const {
  return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_ROW_INDEX);
}

base::Optional<int32_t> ComputedAccessibleNode::rowSpan() const {
  return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_ROW_SPAN);
}

base::Optional<int32_t> ComputedAccessibleNode::setSize() const {
  return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_SET_SIZE);
}

base::Optional<float> ComputedAccessibleNode::valueMax() const {
  return GetFloatAttribute(WebAOMFloatAttribute::AOM_ATTR_VALUE_MAX);
}

base::Optional<float> ComputedAccessibleNode::valueMin() const {
  return GetFloatAttribute(WebAOMFloatAttribute::AOM_ATTR_VALUE_MIN);
}

base::Optional<float> ComputedAccessibleNode::valueNow() const {
  return GetFloatAttribute(WebAOMFloatAttribute::AOM_ATTR_VALUE_NOW);
}

ScriptPromise ComputedAccessibleNode::ensureUpToDate(
    ScriptState* script_state) {
  AXObjectCache* cache = document_->ExistingAXObjectCache();
  DCHECK(cache);
  Element* element = cache->GetElementFromAXID(ax_id_);
  auto* resolver = MakeGarbageCollected<ComputedAccessibleNodePromiseResolver>(
      script_state, *element);
  ScriptPromise promise = resolver->Promise();
  resolver->EnsureUpToDate();
  return promise;
}

const String ComputedAccessibleNode::autocomplete() const {
  return GetStringAttribute(WebAOMStringAttribute::AOM_ATTR_AUTOCOMPLETE);
}

const String ComputedAccessibleNode::checked() const {
  WebString out;
  if (tree_->GetCheckedStateForAXNode(ax_id_, &out)) {
    return out;
  }
  return String();
}

const String ComputedAccessibleNode::keyShortcuts() const {
  return GetStringAttribute(WebAOMStringAttribute::AOM_ATTR_KEY_SHORTCUTS);
}
const String ComputedAccessibleNode::name() const {
  return GetStringAttribute(WebAOMStringAttribute::AOM_ATTR_NAME);
}
const String ComputedAccessibleNode::placeholder() const {
  return GetStringAttribute(WebAOMStringAttribute::AOM_ATTR_PLACEHOLDER);
}

const String ComputedAccessibleNode::role() const {
  WebString out;
  if (tree_->GetRoleForAXNode(ax_id_, &out)) {
    return out;
  }
  return String();
}

const String ComputedAccessibleNode::roleDescription() const {
  return GetStringAttribute(WebAOMStringAttribute::AOM_ATTR_ROLE_DESCRIPTION);
}

const String ComputedAccessibleNode::valueText() const {
  return GetStringAttribute(WebAOMStringAttribute::AOM_ATTR_VALUE_TEXT);
}

ComputedAccessibleNode* ComputedAccessibleNode::parent() const {
  int32_t parent_ax_id;
  if (!tree_->GetParentIdForAXNode(ax_id_, &parent_ax_id)) {
    return nullptr;
  }
  return document_->GetOrCreateComputedAccessibleNode(parent_ax_id, tree_);
}

ComputedAccessibleNode* ComputedAccessibleNode::firstChild() const {
  int32_t child_ax_id;
  if (!tree_->GetFirstChildIdForAXNode(ax_id_, &child_ax_id)) {
    return nullptr;
  }
  return document_->GetOrCreateComputedAccessibleNode(child_ax_id, tree_);
}

ComputedAccessibleNode* ComputedAccessibleNode::lastChild() const {
  int32_t child_ax_id;
  if (!tree_->GetLastChildIdForAXNode(ax_id_, &child_ax_id)) {
    return nullptr;
  }
  return document_->GetOrCreateComputedAccessibleNode(child_ax_id, tree_);
}

ComputedAccessibleNode* ComputedAccessibleNode::previousSibling() const {
  int32_t sibling_ax_id;
  if (!tree_->GetPreviousSiblingIdForAXNode(ax_id_, &sibling_ax_id)) {
    return nullptr;
  }
  return document_->GetOrCreateComputedAccessibleNode(sibling_ax_id, tree_);
}

ComputedAccessibleNode* ComputedAccessibleNode::nextSibling() const {
  int32_t sibling_ax_id;
  if (!tree_->GetNextSiblingIdForAXNode(ax_id_, &sibling_ax_id)) {
    return nullptr;
  }
  return document_->GetOrCreateComputedAccessibleNode(sibling_ax_id, tree_);
}

base::Optional<bool> ComputedAccessibleNode::GetBoolAttribute(
    WebAOMBoolAttribute attr) const {
  bool value;
  if (tree_->GetBoolAttributeForAXNode(ax_id_, attr, &value))
    return value;
  return base::nullopt;
}

base::Optional<int32_t> ComputedAccessibleNode::GetIntAttribute(
    WebAOMIntAttribute attr) const {
  int32_t value;
  if (tree_->GetIntAttributeForAXNode(ax_id_, attr, &value))
    return value;
  return base::nullopt;
}

base::Optional<float> ComputedAccessibleNode::GetFloatAttribute(
    WebAOMFloatAttribute attr) const {
  float value;
  if (tree_->GetFloatAttributeForAXNode(ax_id_, attr, &value))
    return value;
  return base::nullopt;
}

const String ComputedAccessibleNode::GetStringAttribute(
    WebAOMStringAttribute attr) const {
  WebString out;
  if (tree_->GetStringAttributeForAXNode(ax_id_, attr, &out)) {
    return out;
  }
  return String();
}

void ComputedAccessibleNode::Trace(Visitor* visitor) const {
  visitor->Trace(document_);
  ScriptWrappable::Trace(visitor);
}

}  // namespace blink
