// Copyright 2019 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.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CONTENT_CAPTURE_TASK_SESSION_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CONTENT_CAPTURE_TASK_SESSION_H_

#include <utility>

#include "base/callback.h"
#include "base/memory/scoped_refptr.h"
#include "cc/paint/node_id.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/core/content_capture/content_holder.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

class Document;

// This class wraps the captured content and the detached nodes that need to be
// sent out by the ContentCaptureTask, it has a Document to DocumentSession
// mapping, and all data is grouped by document. There are two sources of data:
//
// One is the captured content which is set by the ContentCaptureTask through
// SetCapturedContent() only if the task session is empty, i.e all data must be
// sent before capturing the on-screen content, the captured content is then
// grouped into DocumentSession.
//
// Another is the detached nodes which are set by the ContentCaptureManager,
// they are saved to the DocumentSession directly.
//
// ContentCaptureTask gets the data per document by using
// GetUnsentDocumentSession() and GetNextUnsentNode(), and must send
// all data out before capturing on-screen content again.
class TaskSession final : public GarbageCollected<TaskSession> {
 public:
  // This class manages the captured content and the detached nodes per
  // document, the data is moved to the ContentCaptureTask while required. This
  // class has an instance per document, will be released while the associated
  // document is GC-ed, see TaskSession::to_document_session_.
  class DocumentSession final : public GarbageCollected<DocumentSession> {
   public:
    // The callback for total_sent_nodes_ metrics.
    using SentNodeCountCallback = base::RepeatingCallback<void(size_t)>;

    DocumentSession(const Document& document,
                    SentNodeCountCallback& call_back);
    ~DocumentSession();
    // Add the given |node| to changed node set if the node was sent, return
    // true if succeed.
    bool AddChangedNode(Node& node);
    // Add the given |node| to detached node set if the node was sent, return
    // true if succeed.
    bool AddDetachedNode(const Node& node);
    // Invoked on the content of this document is captured.
    void OnContentCaptured(Node& node, const gfx::Rect& visual_rect);
    // Invoked after TaskSession grouped all captured content.
    void OnGroupingComplete();
    bool HasUnsentData() const {
      return HasUnsentCapturedContent() || HasUnsentChangedContent() ||
             HasUnsentDetachedNodes();
    }
    bool HasUnsentCapturedContent() const {
      return !captured_content_.IsEmpty();
    }
    bool HasUnsentChangedContent() const { return !changed_content_.IsEmpty(); }
    bool HasUnsentDetachedNodes() const { return !detached_nodes_.empty(); }
    WebVector<int64_t> MoveDetachedNodes();
    const Document* GetDocument() const { return document_; }
    bool FirstDataHasSent() const { return first_data_has_sent_; }
    void SetFirstDataHasSent() { first_data_has_sent_ = true; }

    // Removes the unsent node from |captured_content_|, and returns it.
    ContentHolder* GetNextUnsentNode();

    ContentHolder* GetNextChangedNode();

    // Resets the |captured_content_| and the |detached_nodes_|, shall only be
    // used if those data doesn't need to be sent, e.g. there is no
    // WebContentCaptureClient for this document.
    void Reset();

    void Trace(Visitor*) const;

   private:
    // The list of captured content that needs to be sent.
    HeapHashMap<WeakMember<Node>, gfx::Rect> captured_content_;
    // The list of changed nodes that needs to be sent.
    HeapHashMap<WeakMember<Node>, gfx::Rect> changed_content_;
    // The list of content id of node that has been detached from the
    // LayoutTree and needs to be sent.
    WebVector<int64_t> detached_nodes_;

    WeakMember<const Document> document_;
    // A set of weak reference of the node that has been sent.
    HeapHashSet<WeakMember<const Node>> sent_nodes_;
    // A set of node that has been sent in previous capturing and still visible
    // now, it is only valid while TaskSession is groupping the captured
    // content, the nodes are moved and replace the |sent_nodes_| in
    // OnGroupingComplete().
    HeapHashSet<WeakMember<const Node>> visible_sent_nodes_;
    // A set of node whose value has been changed since last capture.
    HeapHashSet<WeakMember<Node>> changed_nodes_;

    bool first_data_has_sent_ = false;
    // This is for the metrics to record the total node that has been sent.
    size_t total_sent_nodes_ = 0;
    // Histogram could be disabed in low time resolution OS, see
    // base::TimeTicks::IsHighResolution and ContentCaptureTask.
    base::Optional<SentNodeCountCallback> callback_;
  };

  TaskSession();

  // Returns the DocumentSession that hasn't been sent.
  DocumentSession* GetNextUnsentDocumentSession();

  // This can only be invoked when all data has been sent (i.e. HasUnsentData()
  // returns False).
  void SetCapturedContent(const Vector<cc::NodeInfo>& captured_content);

  void OnNodeDetached(const Node& node);

  void OnNodeChanged(Node& node);

  bool HasUnsentData() const { return has_unsent_data_; }

  void SetSentNodeCountCallback(
      DocumentSession::SentNodeCountCallback call_back) {
    callback_ = std::move(call_back);
  }

  void Trace(Visitor*) const;

  void ClearDocumentSessionsForTesting();

 private:
  void GroupCapturedContentByDocument(
      const Vector<cc::NodeInfo>& captured_content);
  DocumentSession& EnsureDocumentSession(const Document& doc);
  DocumentSession* GetDocumentSession(const Document& document) const;

  // This owns the DocumentSession which is released along with Document.
  HeapHashMap<WeakMember<const Document>, Member<DocumentSession>>
      to_document_session_;

  // Because the captured content and the detached node are in the
  // DocumentSession, this is used to avoid to iterate all document sessions
  // to find out if there is any of them.
  bool has_unsent_data_ = false;
  DocumentSession::SentNodeCountCallback callback_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CONTENT_CAPTURE_TASK_SESSION_H_
