// Copyright 2020 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 CONTENT_PUBLIC_BROWSER_DOCUMENT_USER_DATA_H_
#define CONTENT_PUBLIC_BROWSER_DOCUMENT_USER_DATA_H_

#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/supports_user_data.h"
#include "content/common/content_export.h"

namespace content {

class RenderFrameHost;

CONTENT_EXPORT base::SupportsUserData::Data* GetDocumentUserData(
    const RenderFrameHost* rfh,
    const void* key);

CONTENT_EXPORT void SetDocumentUserData(
    RenderFrameHost* rfh,
    const void* key,
    std::unique_ptr<base::SupportsUserData::Data> data);

CONTENT_EXPORT void RemoveDocumentUserData(RenderFrameHost* rfh,
                                           const void* key);

// This class approximates the lifetime of a single blink::Document in the
// browser process. At the moment RenderFrameHost can correspond to multiple
// blink::Documents (when RenderFrameHost is reused for same-process
// navigation). DocumentUserData is created when a user of an API
// inherits this class and calls CreateForCurrentDocument.
//
// DocumentUserData is cleared when either:
// - RenderFrameHost is deleted, or
// - A cross-document non-bfcached navigation is committed in the same
// RenderFrameHost i.e., DocumentUserData persists when a document is
// put in the BackForwardCache. It will still be present when the user navigates
// back to the document.
//
// DocumentUserData is assumed to be associated with the document in
// the RenderFrameHost. It can be associated even before RenderFrameHost commits
// i.e., on speculative RFHs and gets destroyed along with speculative RFHs if
// it ends up never committing.
//
// In case of crashes, DocumentUserData's lifetime doesn't match blink::Document
// lifetime. DocumentUserData is not cleared when the RenderFrame is deleted but
// is cleared on a subsequent navigation after a crash. This is done to ensure
// that the data associated with RenderFrameHost is not reset when the non-live
// RenderFrameHost is still in use by browser features like permissions or
// settings, which continue to work on the crashed pages. For more details,
// please refer to crbug.com/1099237.
//
// Note: RenderFrameHost is being replaced with RenderDocumentHost
// [https://crbug.com/936696]. After this is completed, every
// DocumentUserData object will be 1:1 with RenderFrameHost. Also
// RenderFrameHost/RenderDocument would start inheriting directly from
// SupportsUserData then we wouldn't need the use of
// GetDocumentUserData/SetDocumentUserData anymore.
//
// This is similar to WebContentsUserData but attached to a document instead.
// Example usage of DocumentUserData:
//
// --- in foo_document_helper.h ---
// class FooDocumentHelper
//     : public content::DocumentUserData<FooDocumentHelper> {
//  public:
//   ~FooDocumentHelper() override;
//
//   // ... more public stuff here ...
//
//  private:
//   // No public constructors to force going through static methods of
//   // DocumentUserData (e.g. CreateForCurrentDocument).
//   explicit FooDocumentHelper(content::RenderFrameHost* rfh);
//
//   friend DocumentUserData;
//   DOCUMENT_USER_DATA_KEY_DECL();
//
//   // ... more private stuff here ...
// };
//
// --- in foo_document_helper.cc ---
// DOCUMENT_USER_DATA_KEY_IMPL(FooDocumentHelper);
//
// FooDocumentHelper::FooDocumentHelper(content::RenderFrameHost* rfh)
//     : DocumentUserData(rfh) { ... }
template <typename T>
class DocumentUserData : public base::SupportsUserData::Data {
 public:
  template <typename... Args>
  static void CreateForCurrentDocument(RenderFrameHost* rfh, Args&&... args) {
    DCHECK(rfh);
    if (!GetForCurrentDocument(rfh)) {
      T* data = new T(rfh, std::forward<Args>(args)...);
      SetDocumentUserData(rfh, UserDataKey(), base::WrapUnique(data));
    }
  }

  static T* GetForCurrentDocument(RenderFrameHost* rfh) {
    DCHECK(rfh);
    return static_cast<T*>(GetDocumentUserData(rfh, UserDataKey()));
  }

  static T* GetOrCreateForCurrentDocument(RenderFrameHost* rfh) {
    DCHECK(rfh);
    if (auto* data = GetForCurrentDocument(rfh)) {
      return data;
    }

    CreateForCurrentDocument(rfh);
    return GetForCurrentDocument(rfh);
  }

  static void DeleteForCurrentDocument(RenderFrameHost* rfh) {
    DCHECK(rfh);
    DCHECK(GetForCurrentDocument(rfh));
    RemoveDocumentUserData(rfh, UserDataKey());
  }

  // Returns the RenderFrameHost associated with `this` object of a subclass
  // which inherits from DocumentUserData.
  //
  // The returned `render_frame_host()` is guaranteed to live as long as `this`
  // DocumentUserData (due to how UserData works - RenderFrameHost
  // owns `this` UserData).  Note that only the lifetime of
  // `render_frame_host()` is guaranteed, but not its state - e.g. the frame may
  // be `!IsActive()`.
  RenderFrameHost& render_frame_host() const { return *render_frame_host_; }

 protected:
  // TODO(https://crbug.com/1252044): Take a reference instead of a pointer
  // (here + transitively/as-far-as-reasonably-possible in callers).
  explicit DocumentUserData(RenderFrameHost* rfh) : render_frame_host_(rfh) {
    CHECK(rfh);
  }

 private:
  static const void* UserDataKey() { return &T::kUserDataKey; }

  // This is a pointer (rather than a reference) to ensure that go/miracleptr
  // can cover this field (see also //base/memory/raw_ptr.md).
  const raw_ptr<RenderFrameHost> render_frame_host_ = nullptr;
};

// Users won't be able to instantiate the template if they miss declaring the
// user data key.
// This macro declares a static variable inside the class that inherits from
// DocumentUserData. The address of this static variable is used as
// the key to store/retrieve an instance of the class on/from a WebState.
#define DOCUMENT_USER_DATA_KEY_DECL() static const int kUserDataKey = 0

// This macro instantiates the static variable declared by the previous macro.
// It must live in a .cc file to ensure that there is only one instantiation
// of the static variable.
#define DOCUMENT_USER_DATA_KEY_IMPL(Type) const int Type::kUserDataKey

}  // namespace content

#endif  // CONTENT_PUBLIC_BROWSER_DOCUMENT_USER_DATA_H_
