// Copyright 2013 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 "content/browser/dom_storage/dom_storage_context_wrapper.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/services/storage/dom_storage/local_storage_impl.h"
#include "components/services/storage/public/cpp/constants.h"
#include "content/browser/dom_storage/session_storage_context_mojo.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/session_storage_usage_info.h"
#include "content/public/browser/storage_usage_info.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "storage/browser/quota/special_storage_policy.h"
#include "third_party/blink/public/common/features.h"
#include "url/origin.h"

namespace content {
namespace {

const char kSessionStorageDirectory[] = "Session Storage";

void GotMojoSessionStorageUsage(
    scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner,
    DOMStorageContext::GetSessionStorageUsageCallback callback,
    std::vector<SessionStorageUsageInfo> usage) {
  reply_task_runner->PostTask(
      FROM_HERE, base::BindOnce(std::move(callback), std::move(usage)));
}

void AdaptUsageInfo(
    DOMStorageContext::GetLocalStorageUsageCallback callback,
    std::vector<storage::mojom::LocalStorageUsageInfoPtr> usage) {
  std::vector<StorageUsageInfo> result;
  result.reserve(usage.size());
  for (const auto& info : usage) {
    result.emplace_back(info->origin, info->size_in_bytes,
                        info->last_modified_time);
  }
  std::move(callback).Run(result);
}

}  // namespace

class DOMStorageContextWrapper::StoragePolicyObserver
    : public storage::SpecialStoragePolicy::Observer {
 public:
  explicit StoragePolicyObserver(
      scoped_refptr<storage::SpecialStoragePolicy> storage_policy,
      scoped_refptr<DOMStorageContextWrapper> context_wrapper)
      : storage_policy_(std::move(storage_policy)),
        context_wrapper_(std::move(context_wrapper)) {
    storage_policy_->AddObserver(this);
  }

  StoragePolicyObserver(const StoragePolicyObserver&) = delete;
  StoragePolicyObserver& operator=(const StoragePolicyObserver&) = delete;

  ~StoragePolicyObserver() override {
    DCHECK(!context_wrapper_);
    storage_policy_->RemoveObserver(this);
  }

  void DidShutdownContextWrapper() { context_wrapper_.reset(); }

 private:
  // storage::SpecialStoragePolicy::Observer:
  void OnPolicyChanged() override {
    if (!context_wrapper_)
      return;

    base::PostTask(
        FROM_HERE, {BrowserThread::UI},
        base::BindOnce(&DOMStorageContextWrapper::OnStoragePolicyChanged,
                       context_wrapper_));
  }

  const scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
  scoped_refptr<DOMStorageContextWrapper> context_wrapper_;
};

scoped_refptr<DOMStorageContextWrapper> DOMStorageContextWrapper::Create(
    const base::FilePath& profile_path,
    const base::FilePath& local_partition_path,
    storage::SpecialStoragePolicy* special_storage_policy) {
  base::FilePath data_path;
  if (!profile_path.empty())
    data_path = profile_path.Append(local_partition_path);

  auto mojo_task_runner =
      base::CreateSingleThreadTaskRunner({BrowserThread::IO});

  // TODO(https://crbug.com/1000959): This should be bound in an instance of
  // the Storage Service. For now we bind it alone on the IO thread because
  // that's where the implementation has effectively lived for some time.
  mojo::Remote<storage::mojom::LocalStorageControl> local_storage_control;
  mojo_task_runner->PostTask(
      FROM_HERE,
      base::BindOnce(
          [](const base::FilePath& storage_root,
             mojo::PendingReceiver<storage::mojom::LocalStorageControl>
                 receiver) {
            // Deletes itself on shutdown completion.
            new storage::LocalStorageImpl(
                storage_root,
                base::CreateSingleThreadTaskRunner({BrowserThread::IO}),
                base::CreateSequencedTaskRunner(
                    {base::ThreadPool(), base::MayBlock(),
                     base::TaskPriority::USER_BLOCKING,
                     base::TaskShutdownBehavior::BLOCK_SHUTDOWN}),
                std::move(receiver));
          },
          data_path, local_storage_control.BindNewPipeAndPassReceiver()));

  SessionStorageContextMojo* mojo_session_state = nullptr;
  mojo_session_state = new SessionStorageContextMojo(
      data_path,
      base::CreateSequencedTaskRunner(
          {base::MayBlock(), base::ThreadPool(),
           base::TaskShutdownBehavior::BLOCK_SHUTDOWN}),
      mojo_task_runner,
#if defined(OS_ANDROID)
      // On Android there is no support for session storage restoring, and
      // since the restoring code is responsible for database cleanup, we must
      // manually delete the old database here before we open it.
      SessionStorageContextMojo::BackingMode::kClearDiskStateOnOpen,
#else
      profile_path.empty()
          ? SessionStorageContextMojo::BackingMode::kNoDisk
          : SessionStorageContextMojo::BackingMode::kRestoreDiskState,
#endif
      std::string(kSessionStorageDirectory));

  auto wrapper = base::WrapRefCounted(new DOMStorageContextWrapper(
      mojo_task_runner, mojo_session_state, std::move(local_storage_control),
      special_storage_policy));

  if (special_storage_policy) {
    // If there's a SpecialStoragePolicy, ensure the wrapper is observing it on
    // the IO thread and query the initial set of in-use origins ASAP.
    wrapper->storage_policy_observer_ =
        base::SequenceBound<StoragePolicyObserver>(
            base::CreateSequencedTaskRunner(BrowserThread::IO),
            base::WrapRefCounted(special_storage_policy), wrapper);

    wrapper->local_storage_control_->GetUsage(base::BindOnce(
        &DOMStorageContextWrapper::OnStartupUsageRetrieved, wrapper));
  }

  return wrapper;
}

DOMStorageContextWrapper::DOMStorageContextWrapper(
    scoped_refptr<base::SequencedTaskRunner> mojo_task_runner,
    SessionStorageContextMojo* mojo_session_storage_context,
    mojo::Remote<storage::mojom::LocalStorageControl> local_storage_control,
    storage::SpecialStoragePolicy* special_storage_policy)
    : mojo_session_state_(mojo_session_storage_context),
      mojo_task_runner_(std::move(mojo_task_runner)),
      local_storage_control_(std::move(local_storage_control)),
      storage_policy_(special_storage_policy) {
  memory_pressure_listener_.reset(new base::MemoryPressureListener(
      base::BindRepeating(&DOMStorageContextWrapper::OnMemoryPressure,
                          base::Unretained(this))));
}

DOMStorageContextWrapper::~DOMStorageContextWrapper() {
  DCHECK(!local_storage_control_)
      << "Shutdown should be called before destruction";
}

storage::mojom::LocalStorageControl*
DOMStorageContextWrapper::GetLocalStorageControl() {
  DCHECK(local_storage_control_);
  return local_storage_control_.get();
}

void DOMStorageContextWrapper::GetLocalStorageUsage(
    GetLocalStorageUsageCallback callback) {
  if (!local_storage_control_) {
    // Shutdown() has been called.
    std::move(callback).Run(std::vector<StorageUsageInfo>());
    return;
  }

  local_storage_control_->GetUsage(
      base::BindOnce(&AdaptUsageInfo, std::move(callback)));
}

void DOMStorageContextWrapper::GetSessionStorageUsage(
    GetSessionStorageUsageCallback callback) {
  if (!mojo_session_state_) {
    // Shutdown() has been called.
    std::move(callback).Run(std::vector<SessionStorageUsageInfo>());
    return;
  }
  // base::Unretained is safe here, because the mojo_session_state_ won't be
  // deleted until a ShutdownAndDelete task has been ran on the
  // mojo_task_runner_, and as soon as that task is posted,
  // mojo_session_state_ is set to null, preventing further tasks from being
  // queued.
  mojo_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&SessionStorageContextMojo::GetStorageUsage,
                     base::Unretained(mojo_session_state_),
                     base::BindOnce(&GotMojoSessionStorageUsage,
                                    base::ThreadTaskRunnerHandle::Get(),
                                    std::move(callback))));
}

void DOMStorageContextWrapper::DeleteLocalStorage(const url::Origin& origin,
                                                  base::OnceClosure callback) {
  DCHECK(callback);
  if (!local_storage_control_) {
    // Shutdown() has been called.
    std::move(callback).Run();
    return;
  }

  local_storage_control_->DeleteStorage(origin, std::move(callback));
}

void DOMStorageContextWrapper::PerformLocalStorageCleanup(
    base::OnceClosure callback) {
  DCHECK(callback);
  if (!local_storage_control_) {
    // Shutdown() has been called.
    std::move(callback).Run();
    return;
  }

  local_storage_control_->CleanUpStorage(std::move(callback));
}

void DOMStorageContextWrapper::DeleteSessionStorage(
    const SessionStorageUsageInfo& usage_info,
    base::OnceClosure callback) {
  if (!mojo_session_state_) {
    // Shutdown() has been called.
    std::move(callback).Run();
  }
  // base::Unretained is safe here, because the mojo_session_state_ won't be
  // deleted until a ShutdownAndDelete task has been ran on the
  // mojo_task_runner_, and as soon as that task is posted,
  // mojo_session_state_ is set to null, preventing further tasks from being
  // queued.
  mojo_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&SessionStorageContextMojo::DeleteStorage,
                                base::Unretained(mojo_session_state_),
                                url::Origin::Create(usage_info.origin),
                                usage_info.namespace_id, std::move(callback)));
}

void DOMStorageContextWrapper::PerformSessionStorageCleanup(
    base::OnceClosure callback) {
  DCHECK(callback);
  if (!mojo_session_state_) {
    // Shutdown() has been called.
    std::move(callback).Run();
  }
  // base::Unretained is safe here, because the mojo_session_state_ won't be
  // deleted until a ShutdownAndDelete task has been ran on the
  // mojo_task_runner_, and as soon as that task is posted,
  // mojo_session_state_ is set to null, preventing further tasks from being
  // queued.
  mojo_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&SessionStorageContextMojo::PerformStorageCleanup,
                     base::Unretained(mojo_session_state_),
                     std::move(callback)));
}

scoped_refptr<SessionStorageNamespace>
DOMStorageContextWrapper::RecreateSessionStorage(
    const std::string& namespace_id) {
  return SessionStorageNamespaceImpl::Create(this, namespace_id);
}

void DOMStorageContextWrapper::StartScavengingUnusedSessionStorage() {
  if (!mojo_session_state_) {
    // Shutdown() has been called.
    return;
  }
  // base::Unretained is safe here, because the mojo_session_state_ won't be
  // deleted until a ShutdownAndDelete task has been ran on the
  // mojo_task_runner_, and as soon as that task is posted,
  // mojo_session_state_ is set to null, preventing further tasks from being
  // queued.
  mojo_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&SessionStorageContextMojo::ScavengeUnusedNamespaces,
                     base::Unretained(mojo_session_state_),
                     base::OnceClosure()));
}

void DOMStorageContextWrapper::SetForceKeepSessionState() {
  if (!local_storage_control_) {
    // Shutdown() has been called.
    return;
  }

  local_storage_control_->ForceKeepSessionState();
}

void DOMStorageContextWrapper::Shutdown() {
  // Signals the implementation to perform shutdown operations.
  local_storage_control_.reset();

  if (mojo_session_state_) {
    mojo_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&SessionStorageContextMojo::ShutdownAndDelete,
                                  base::Unretained(mojo_session_state_)));
    mojo_session_state_ = nullptr;
  }
  memory_pressure_listener_.reset();

  if (storage_policy_observer_) {
    // Make sure the observer drops its reference to |this|.
    storage_policy_observer_.Post(
        FROM_HERE, &StoragePolicyObserver::DidShutdownContextWrapper);
  }
}

void DOMStorageContextWrapper::Flush() {
  if (local_storage_control_)
    local_storage_control_->Flush(base::NullCallback());

  if (mojo_session_state_) {
    // base::Unretained is safe here, because the mojo_session_state_ won't be
    // deleted until a ShutdownAndDelete task has been ran on the
    // mojo_task_runner_, and as soon as that task is posted,
    // mojo_session_state_ is set to null, preventing further tasks from being
    // queued.
    mojo_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&SessionStorageContextMojo::Flush,
                                  base::Unretained(mojo_session_state_)));
  }
}

void DOMStorageContextWrapper::OpenLocalStorage(
    const url::Origin& origin,
    mojo::PendingReceiver<blink::mojom::StorageArea> receiver) {
  DCHECK(local_storage_control_);
  local_storage_control_->BindStorageArea(origin, std::move(receiver));
  if (storage_policy_) {
    EnsureLocalStorageOriginIsTracked(origin.GetURL());
    OnStoragePolicyChanged();
  }
}

void DOMStorageContextWrapper::OpenSessionStorage(
    int process_id,
    const std::string& namespace_id,
    mojo::ReportBadMessageCallback bad_message_callback,
    mojo::PendingReceiver<blink::mojom::SessionStorageNamespace> receiver) {
  DCHECK(mojo_session_state_);
  // The bad message callback must be called on the same sequenced task runner
  // as the binding set. It cannot be called from our own mojo task runner.
  auto wrapped_bad_message_callback = base::BindOnce(
      [](mojo::ReportBadMessageCallback bad_message_callback,
         scoped_refptr<base::SequencedTaskRunner> bindings_runner,
         const std::string& error) {
        bindings_runner->PostTask(
            FROM_HERE, base::BindOnce(std::move(bad_message_callback), error));
      },
      std::move(bad_message_callback), base::SequencedTaskRunnerHandle::Get());
  // base::Unretained is safe here, because the mojo_state_ won't be deleted
  // until a ShutdownAndDelete task has been ran on the mojo_task_runner_, and
  // as soon as that task is posted, mojo_state_ is set to null, preventing
  // further tasks from being queued.
  mojo_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&SessionStorageContextMojo::OpenSessionStorage,
                     base::Unretained(mojo_session_state_), process_id,
                     namespace_id, std::move(wrapped_bad_message_callback),
                     std::move(receiver)));
}

scoped_refptr<SessionStorageNamespaceImpl>
DOMStorageContextWrapper::MaybeGetExistingNamespace(
    const std::string& namespace_id) const {
  base::AutoLock lock(alive_namespaces_lock_);
  auto it = alive_namespaces_.find(namespace_id);
  return (it != alive_namespaces_.end()) ? it->second : nullptr;
}

void DOMStorageContextWrapper::AddNamespace(
    const std::string& namespace_id,
    SessionStorageNamespaceImpl* session_namespace) {
  base::AutoLock lock(alive_namespaces_lock_);
  DCHECK(alive_namespaces_.find(namespace_id) == alive_namespaces_.end());
  alive_namespaces_[namespace_id] = session_namespace;
}

void DOMStorageContextWrapper::RemoveNamespace(
    const std::string& namespace_id) {
  base::AutoLock lock(alive_namespaces_lock_);
  DCHECK(alive_namespaces_.find(namespace_id) != alive_namespaces_.end());
  alive_namespaces_.erase(namespace_id);
}

void DOMStorageContextWrapper::OnMemoryPressure(
    base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
  PurgeOption purge_option = PURGE_UNOPENED;
  if (memory_pressure_level ==
      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
    purge_option = PURGE_AGGRESSIVE;
  }
  PurgeMemory(purge_option);
}

void DOMStorageContextWrapper::PurgeMemory(PurgeOption purge_option) {
  if (!local_storage_control_) {
    // Shutdown was called.
    return;
  }

  if (purge_option == PURGE_AGGRESSIVE) {
    local_storage_control_->PurgeMemory();

    // base::Unretained is safe here, because the mojo_session_state_ won't be
    // deleted until a ShutdownAndDelete task has been ran on the
    // mojo_task_runner_, and as soon as that task is posted,
    // mojo_session_state_ is set to null, preventing further tasks from being
    // queued.
    mojo_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&SessionStorageContextMojo::PurgeMemory,
                                  base::Unretained(mojo_session_state_)));
  }
}

void DOMStorageContextWrapper::OnStartupUsageRetrieved(
    std::vector<storage::mojom::LocalStorageUsageInfoPtr> usage) {
  for (const auto& info : usage)
    EnsureLocalStorageOriginIsTracked(info->origin.GetURL());
  OnStoragePolicyChanged();
}

void DOMStorageContextWrapper::EnsureLocalStorageOriginIsTracked(
    const GURL& origin) {
  DCHECK(storage_policy_);
  auto it = local_storage_origins_.find(origin);
  if (it == local_storage_origins_.end())
    local_storage_origins_[origin] = {};
}

void DOMStorageContextWrapper::OnStoragePolicyChanged() {
  if (!local_storage_control_)
    return;

  // Scan for any relevant changes to policy regarding origins we know we're
  // managing.
  std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> policy_updates;
  for (auto& entry : local_storage_origins_) {
    const GURL& origin = entry.first;
    LocalStorageOriginState& state = entry.second;
    state.should_purge_on_shutdown = ShouldPurgeLocalStorageOnShutdown(origin);
    if (state.should_purge_on_shutdown != state.will_purge_on_shutdown) {
      state.will_purge_on_shutdown = state.should_purge_on_shutdown;
      policy_updates.push_back(storage::mojom::LocalStoragePolicyUpdate::New(
          url::Origin::Create(origin), state.should_purge_on_shutdown));
    }
  }

  if (!policy_updates.empty())
    local_storage_control_->ApplyPolicyUpdates(std::move(policy_updates));
}

bool DOMStorageContextWrapper::ShouldPurgeLocalStorageOnShutdown(
    const GURL& origin) {
  if (!storage_policy_)
    return false;
  return storage_policy_->IsStorageSessionOnly(origin) &&
         !storage_policy_->IsStorageProtected(origin);
}

}  // namespace content
