// 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 "components/offline_items_collection/core/throttled_offline_content_provider.h"

#include <utility>

#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/offline_items_collection/core/offline_item.h"

namespace offline_items_collection {
namespace {
const int kDelayBetweenUpdatesMs = 1000;
}  // namespace

ThrottledOfflineContentProvider::ThrottledOfflineContentProvider(
    OfflineContentProvider* provider)
    : ThrottledOfflineContentProvider(
          base::TimeDelta::FromMilliseconds(kDelayBetweenUpdatesMs),
          provider) {}

ThrottledOfflineContentProvider::ThrottledOfflineContentProvider(
    const base::TimeDelta& delay_between_updates,
    OfflineContentProvider* provider)
    : delay_between_updates_(delay_between_updates),
      last_update_time_(base::TimeTicks::Now()),
      update_queued_(false),
      wrapped_provider_(provider),
      weak_ptr_factory_(this) {
  DCHECK(wrapped_provider_);
  wrapped_provider_->AddObserver(this);
}

ThrottledOfflineContentProvider::~ThrottledOfflineContentProvider() {
  wrapped_provider_->RemoveObserver(this);
}

bool ThrottledOfflineContentProvider::AreItemsAvailable() {
  return wrapped_provider_->AreItemsAvailable();
}

void ThrottledOfflineContentProvider::OpenItem(const ContentId& id) {
  wrapped_provider_->OpenItem(id);
  FlushUpdates();
}

void ThrottledOfflineContentProvider::RemoveItem(const ContentId& id) {
  wrapped_provider_->RemoveItem(id);
  FlushUpdates();
}

void ThrottledOfflineContentProvider::CancelDownload(const ContentId& id) {
  wrapped_provider_->CancelDownload(id);
  FlushUpdates();
}

void ThrottledOfflineContentProvider::PauseDownload(const ContentId& id) {
  wrapped_provider_->PauseDownload(id);
  FlushUpdates();
}

void ThrottledOfflineContentProvider::ResumeDownload(const ContentId& id,
                                                     bool has_user_gesture) {
  wrapped_provider_->ResumeDownload(id, has_user_gesture);
  FlushUpdates();
}

void ThrottledOfflineContentProvider::GetItemById(const ContentId& id,
                                                  SingleItemCallback callback) {
  wrapped_provider_->GetItemById(
      id, base::BindOnce(&ThrottledOfflineContentProvider::OnGetItemByIdDone,
                         weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

void ThrottledOfflineContentProvider::GetAllItems(
    MultipleItemCallback callback) {
  wrapped_provider_->GetAllItems(
      base::BindOnce(&ThrottledOfflineContentProvider::OnGetAllItemsDone,
                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

void ThrottledOfflineContentProvider::OnGetAllItemsDone(
    MultipleItemCallback callback,
    const OfflineItemList& items) {
  for (const auto item : items)
    UpdateItemIfPresent(item);
  std::move(callback).Run(items);
}

void ThrottledOfflineContentProvider::OnGetItemByIdDone(
    SingleItemCallback callback,
    const base::Optional<OfflineItem>& item) {
  if (item.has_value())
    UpdateItemIfPresent(item.value());
  std::move(callback).Run(item);
}

void ThrottledOfflineContentProvider::GetVisualsForItem(
    const ContentId& id,
    const VisualsCallback& callback) {
  wrapped_provider_->GetVisualsForItem(id, callback);
}

void ThrottledOfflineContentProvider::AddObserver(
    OfflineContentProvider::Observer* observer) {
  DCHECK(observer);
  observers_.AddObserver(observer);
  if (!wrapped_provider_->AreItemsAvailable())
    return;

  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::Bind(&ThrottledOfflineContentProvider::NotifyItemsAvailable,
                 weak_ptr_factory_.GetWeakPtr(), base::Unretained(observer)));
}

void ThrottledOfflineContentProvider::RemoveObserver(
    OfflineContentProvider::Observer* observer) {
  observers_.RemoveObserver(observer);
}

void ThrottledOfflineContentProvider::OnItemsAvailable(
    OfflineContentProvider* provider) {
  DCHECK_EQ(provider, wrapped_provider_);
  for (auto& observer : observers_)
    observer.OnItemsAvailable(this);
}

void ThrottledOfflineContentProvider::OnItemsAdded(
    const OfflineItemList& items) {
  for (auto& observer : observers_)
    observer.OnItemsAdded(items);
}

void ThrottledOfflineContentProvider::OnItemRemoved(const ContentId& id) {
  updates_.erase(id);
  for (auto& observer : observers_)
    observer.OnItemRemoved(id);
}

void ThrottledOfflineContentProvider::OnItemUpdated(const OfflineItem& item) {
  updates_[item.id] = item;

  // If we already queued an update, we're throttling, just wait until the
  // update passes through.
  if (update_queued_)
    return;

  // If we haven't sent an update recently, let the update go through.
  base::TimeDelta current_delay = base::TimeTicks::Now() - last_update_time_;
  if (current_delay >= delay_between_updates_) {
    FlushUpdates();
    return;
  }

  // Queue the update so we wait for the proper amount of time before notifying
  // observers.
  update_queued_ = true;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&ThrottledOfflineContentProvider::FlushUpdates,
                 weak_ptr_factory_.GetWeakPtr()),
      delay_between_updates_ - current_delay);
}

void ThrottledOfflineContentProvider::NotifyItemsAvailable(
    OfflineContentProvider::Observer* observer) {
  if (!observers_.HasObserver(observer))
    return;
  observer->OnItemsAvailable(this);
}

void ThrottledOfflineContentProvider::UpdateItemIfPresent(
    const OfflineItem& item) {
  OfflineItemMap::iterator it = updates_.find(item.id);
  if (it != updates_.end())
    it->second = item;
}

void ThrottledOfflineContentProvider::FlushUpdates() {
  last_update_time_ = base::TimeTicks::Now();
  update_queued_ = false;

  OfflineItemMap updates = std::move(updates_);
  for (auto item_pair : updates) {
    for (auto& observer : observers_)
      observer.OnItemUpdated(item_pair.second);
  }
}

}  // namespace offline_items_collection
