// Copyright 2018 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/html/anchor_element_metrics_sender.h"

#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/anchor_element_metrics.h"
#include "third_party/blink/renderer/core/html/html_anchor_element.h"
#include "ui/gfx/geometry/mojom/geometry.mojom-shared.h"

namespace blink {

namespace {

// Returns true if |anchor_element| should be discarded, and not used for
// navigation prediction.
bool ShouldDiscardAnchorElement(const HTMLAnchorElement& anchor_element) {
  Frame* frame = anchor_element.GetDocument().GetFrame();
  auto* local_frame = DynamicTo<LocalFrame>(frame);
  if (!local_frame)
    return true;
  return local_frame->IsAdSubframe();
}

}  // namespace

// static
const char AnchorElementMetricsSender::kSupplementName[] =
    "DocumentAnchorElementMetricsSender";

AnchorElementMetricsSender::~AnchorElementMetricsSender() = default;

// static
AnchorElementMetricsSender* AnchorElementMetricsSender::From(
    Document& document) {
  DCHECK(HasAnchorElementMetricsSender(document));

  AnchorElementMetricsSender* sender =
      Supplement<Document>::From<AnchorElementMetricsSender>(document);
  if (!sender) {
    sender = MakeGarbageCollected<AnchorElementMetricsSender>(document);
    ProvideTo(document, sender);
  }
  return sender;
}

// static
bool AnchorElementMetricsSender::HasAnchorElementMetricsSender(
    Document& document) {
  bool is_feature_enabled =
      base::FeatureList::IsEnabled(features::kNavigationPredictor);
  const KURL& url = document.BaseURL();
  return is_feature_enabled && !document.ParentDocument() && url.IsValid() &&
         url.ProtocolIsInHTTPFamily();
}

void AnchorElementMetricsSender::SendClickedAnchorMetricsToBrowser(
    mojom::blink::AnchorElementMetricsPtr metric) {
  if (!AssociateInterface())
    return;

  metrics_host_->ReportAnchorElementMetricsOnClick(std::move(metric));
}

void AnchorElementMetricsSender::SendAnchorMetricsVectorToBrowser(
    Vector<mojom::blink::AnchorElementMetricsPtr> metrics,
    const IntSize& viewport_size) {
  if (!AssociateInterface())
    return;

  metrics_host_->ReportAnchorElementMetricsOnLoad(std::move(metrics),
                                                  gfx::Size(viewport_size));
  has_onload_report_sent_ = true;
  anchor_elements_.clear();
}

void AnchorElementMetricsSender::AddAnchorElement(HTMLAnchorElement& element) {
  if (has_onload_report_sent_)
    return;

  bool is_ad_frame_element = ShouldDiscardAnchorElement(element);

  // We ignore anchor elements that are in ad frames.
  if (is_ad_frame_element)
    return;

  anchor_elements_.insert(&element);
}

const HeapHashSet<Member<HTMLAnchorElement>>&
AnchorElementMetricsSender::GetAnchorElements() const {
  return anchor_elements_;
}

void AnchorElementMetricsSender::Trace(Visitor* visitor) const {
  visitor->Trace(anchor_elements_);
  visitor->Trace(metrics_host_);
  Supplement<Document>::Trace(visitor);
}

bool AnchorElementMetricsSender::AssociateInterface() {
  if (metrics_host_.is_bound())
    return true;

  Document* document = GetSupplementable();
  // Unable to associate since no frame is attached.
  if (!document->GetFrame())
    return false;

  document->GetFrame()->GetBrowserInterfaceBroker().GetInterface(
      metrics_host_.BindNewPipeAndPassReceiver(
          document->GetExecutionContext()->GetTaskRunner(
              TaskType::kInternalDefault)));
  return true;
}

AnchorElementMetricsSender::AnchorElementMetricsSender(Document& document)
    : Supplement<Document>(document),
      metrics_host_(document.GetExecutionContext()) {
  DCHECK(!document.ParentDocument());
}

void AnchorElementMetricsSender::DidFinishLifecycleUpdate(
    const LocalFrameView& local_frame_view) {
  // Check that layout is stable. If it is, we can perform the onload update and
  // stop observing future events.
  Document* document = local_frame_view.GetFrame().GetDocument();
  if (document->Lifecycle().GetState() <
      DocumentLifecycle::kAfterPerformLayout) {
    return;
  }

  // Stop listening to updates, as the onload report can be sent now.
  document->View()->UnregisterFromLifecycleNotifications(this);

  // Send onload report.
  AnchorElementMetrics::MaybeReportViewportMetricsOnLoad(*document);
}

}  // namespace blink
